Example #1
0
    def _get_features(self, state: tuple[Pokemon, Pokemon], move: Move):
        # TODO: Optimize feature extraction
        pokemon_a, pokemon_b = state
        type_mod = Type.dmg_modifier(move.info.type, pokemon_b.species.types[0]) * \
               (Type.dmg_modifier(move.info.type, pokemon_b.species.types[1]) if len(pokemon_b.species.types) > 1 else 1)
        type_mod /= 4  # Normalize the value between 0 and 1

        dmg_class_mod_stat_atk, dmg_class_mod_stat_def = (pokemon_a.stats.attack, pokemon_b.stats.defense) \
            if move.info.damage_class is DamageClass.PHYSICAL else (pokemon_a.stats.special, pokemon_b.stats.special)
        dmg_class_mod = (dmg_class_mod_stat_atk /
                         (dmg_class_mod_stat_atk + dmg_class_mod_stat_def))
        return [
            pokemon_a.hp / pokemon_a.stats.total_hp,
            pokemon_b.hp / pokemon_b.stats.total_hp,
            dmg_class_mod,
            type_mod,
            (move.info.power / 250),
            (move.info.accuracy if move.info.accuracy is not None else 1),
            # move.info.hit_info.min_hits,
            # move.info.hit_info.max_hits,
            int(move.info.high_crit_ratio),
            # move.info.priority,
            move.info.drain,
            # move.info.healing,
            # int(move.pp == 0)
            # TODO: Add more features
        ]
Example #2
0
    def _calc_modifier(self, attacking_pokemon: PokemonSpecies,
                       defending_pokemon: PokemonSpecies,
                       move_used: MoveInfo) -> float:
        rand_modifier = random.uniform(0.85, 1.0)
        if move_used.name == ATTACK_SELF:
            return rand_modifier

        stab = 1.5 if move_used.type in attacking_pokemon.types else 1
        type_modifier = Type.dmg_modifier(move_used.type,
                                          defending_pokemon.types[0])
        if len(defending_pokemon.types) > 1:
            type_modifier *= Type.dmg_modifier(move_used.type,
                                               defending_pokemon.types[1])
        return rand_modifier * stab * type_modifier
Example #3
0
 def _types_advantage(self, pokemon_a: PokemonSpecies,
                      pokemon_b: PokemonSpecies) -> Matchup:
     weight = math.prod(
         Type.dmg_modifier(at, dt)
         for at, dt in itertools.product(pokemon_a.types, pokemon_b.types))
     if weight > 1:
         return Matchup.ADVANTAGEOUS
     elif weight < 1:
         return Matchup.DISADVANTAGEOUS
     else:
         return Matchup.NEUTRAL