def get_pokemon( self, identifier: str, force_self_team: bool = False, details: str = "", request: Optional[dict] = None, ) -> Pokemon: """Returns the Pokemon object corresponding to given identifier. Can force to return object from the player's team if force_self_team is True. If the Pokemon object does not exist, it will be created. Details can be given, which is necessary to initialize alternate forms (eg. alolan pokemons) properly. :param identifier: The identifier to use to retrieve the pokemon. :type identifier: str :param force_self_team: Wheter to force returning a Pokemon from the player's team. Defaults to False. :type details: str, optional :param details: Detailled information about the pokemon. Defaults to ''. :type force_self_team: bool, optional, defaults to False :return: The corresponding pokemon object. :rtype: Pokemon :raises AssertionError: If the team has too many pokemons, as determined by the teamsize component of battle initialisation. """ if identifier[3] != " ": identifier = identifier[:2] + identifier[3:] if identifier in self._team: return self._team[identifier] elif identifier in self._opponent_team: return self._opponent_team[identifier] player_role = identifier[:2] is_mine = player_role == self._player_role if is_mine or force_self_team: team: Dict[str, Pokemon] = self._team else: team: Dict[str, Pokemon] = self._opponent_team if self._team_size and len(team) >= self._team_size[player_role]: raise ValueError( "%s's team already has %d pokemons: cannot add %s to %s" % ( player_role, self._team_size[player_role], identifier[:2], ", ".join(team.keys()), ) ) if request: team[identifier] = Pokemon(request_pokemon=request) elif details: team[identifier] = Pokemon(details=details) else: species = identifier[4:] team[identifier] = Pokemon(species=species) return team[identifier]
def test_pokemon_types(): # single type mon = Pokemon(species="pikachu") assert mon.type_1 == PokemonType.ELECTRIC assert mon.type_2 is None # dual type mon = Pokemon(species="garchomp") assert mon.type_1 == PokemonType.DRAGON assert mon.type_2 == PokemonType.GROUND # alolan forms mon = Pokemon(species="raichualola") assert mon.type_1 == PokemonType.ELECTRIC assert mon.type_2 == PokemonType.PSYCHIC # megas mon = Pokemon(species="altaria") assert mon.type_1 == PokemonType.DRAGON assert mon.type_2 == PokemonType.FLYING mon._mega_evolve("altariaite") assert mon.type_1 == PokemonType.DRAGON assert mon.type_2 == PokemonType.FAIRY # primals mon = Pokemon(species="groudon") assert mon.type_1 == PokemonType.GROUND assert mon.type_2 is None mon._primal() assert mon.type_1 == PokemonType.GROUND assert mon.type_2 == PokemonType.FIRE
def test_simple_heuristics_player_should_dynamax(): PseudoBattle = namedtuple( "PseudoBattle", ["active_pokemon", "opponent_active_pokemon", "team", "can_dynamax"], ) player = SimpleHeuristicsPlayer(start_listening=False) battle = PseudoBattle(Pokemon(species="charmander"), Pokemon(species="charmander"), {}, False) assert player._should_dynamax(battle, 4) is False battle = PseudoBattle(Pokemon(species="charmander"), Pokemon(species="charmander"), {}, True) assert player._should_dynamax(battle, 1) is True battle.active_pokemon._set_hp("100/100") battle.team["charmander"] = battle.active_pokemon assert player._should_dynamax(battle, 4) is True battle = PseudoBattle( Pokemon(species="squirtle"), Pokemon(species="charmander"), { "kakuna": Pokemon(species="kakuna"), "venusaur": Pokemon(species="venusaur"), "charmander": Pokemon(species="charmander"), }, True, ) for mon in battle.team.values(): mon._set_hp("100/100") battle.active_pokemon._set_hp("100/100") battle.opponent_active_pokemon._set_hp("100/100") assert player._should_dynamax(battle, 4) is True
def test_pokemon_damage_multiplier(): mon = Pokemon(species="pikachu") assert mon.damage_multiplier(PokemonType.GROUND) == 2 assert mon.damage_multiplier(PokemonType.ELECTRIC) == 0.5 mon = Pokemon(species="garchomp") assert mon.damage_multiplier(Move("icebeam")) == 4 assert mon.damage_multiplier(Move("dracometeor")) == 2 mon = Pokemon(species="linoone") assert mon.damage_multiplier(Move("closecombat")) == 2 assert mon.damage_multiplier(PokemonType.GHOST) == 0
def test_simple_heuristics_player(): player = SimpleHeuristicsPlayer(start_listening=False) PseudoBattle = namedtuple( "PseudoBattle", ( "active_pokemon", "opponent_active_pokemon", "available_moves", "available_switches", "team", "can_dynamax", "side_conditions", "opponent_side_conditions", ), ) battle = PseudoBattle( Pokemon(species="dragapult"), Pokemon(species="gengar"), [], [Pokemon(species="togekiss")], {}, True, set(), set(), ) battle.active_pokemon._last_request["stats"] = { stat: 100 for stat in battle.active_pokemon.base_stats } battle.available_switches[0]._set_hp("100/100") assert player.choose_move(battle).message == "/choose switch togekiss" battle.available_moves.append(Move("quickattack")) assert player.choose_move(battle).message == "/choose move quickattack" battle.available_moves.append(Move("flamethrower")) assert player.choose_move(battle).message == "/choose move flamethrower" battle.available_moves.append(Move("dracometeor")) assert player.choose_move(battle).message == "/choose move dracometeor" battle.active_pokemon._boost("atk", -3) battle.active_pokemon._boost("spa", -3) battle.available_switches.append(Pokemon(species="sneasel")) battle.available_switches[1]._set_hp("100/100") assert player.choose_move(battle).message == "/choose switch sneasel"
def test_pokemon_boosts(): mon = Pokemon(species="blastoise") assert set(mon.boosts.values()) == {0} mon._boost("accuracy", 1) assert set(mon.boosts.values()) == {0, 1} assert mon.boosts["accuracy"] == 1 mon._boost("accuracy", 2) assert mon.boosts["accuracy"] == 3 mon._boost("accuracy", 2) assert mon.boosts["accuracy"] == 5 mon._boost("accuracy", 1) assert mon.boosts["accuracy"] == 6 mon._boost("accuracy", -1) assert mon.boosts["accuracy"] == 5 mon._boost("accuracy", 5) assert mon.boosts["accuracy"] == 6 mon._boost("accuracy", -10) assert mon.boosts["accuracy"] == -4 mon._boost("accuracy", -10) assert mon.boosts["accuracy"] == -6 mon._boost("spd", 2) mon._clear_negative_boosts() assert mon.boosts["accuracy"] == 0 assert mon.boosts["spd"] == 2
def test_max_base_power_player(): player = MaxBasePowerPlayer(start_listening=False) PseudoBattle = namedtuple( "PseudoBattle", ( "available_moves", "available_switches", "can_z_move", "can_dynamax", "can_mega_evolve", ), ) battle = PseudoBattle([], [], False, False, False) assert player.choose_move(battle) == "/choose default" battle.available_switches.append(Pokemon(species="ponyta")) assert player.choose_move(battle) == "/choose switch ponyta" battle.available_moves.append(Move("protect")) assert player.choose_move(battle) == "/choose move protect" battle.available_moves.append(Move("quickattack")) assert player.choose_move(battle) == "/choose move quickattack" battle.available_moves.append(Move("flamethrower")) assert player.choose_move(battle) == "/choose move flamethrower"
def test_simple_heuristics_player_should_switch_out(): PseudoBattle = namedtuple( "PseudoBattle", ["active_pokemon", "opponent_active_pokemon", "available_switches"], ) player = SimpleHeuristicsPlayer(start_listening=False) battle = PseudoBattle(Pokemon(species="charmander"), Pokemon(species="charmander"), []) assert player._should_switch_out(battle) is False battle.available_switches.append(Pokemon(species="venusaur")) assert player._should_switch_out(battle) is False battle.available_switches.append(Pokemon(species="gyarados")) assert player._should_switch_out(battle) is False battle.active_pokemon._boost("spa", -3) battle.active_pokemon.stats.update({"atk": 10, "spa": 20}) assert player._should_switch_out(battle) is True battle.active_pokemon.stats.update({"atk": 30, "spa": 20}) assert player._should_switch_out(battle) is False battle.active_pokemon._boost("atk", -3) assert player._should_switch_out(battle) is True battle = PseudoBattle( Pokemon(species="gible"), Pokemon(species="mamoswine"), [Pokemon(species="charizard")], ) assert player._should_switch_out(battle) is True
def test_random_player(): from poke_env.player import player as player_pkg from poke_env.environment.battle import Battle player = RandomPlayer(start_listening=False) PseudoBattle = namedtuple( "PseudoBattle", ( "available_moves", "available_switches", "can_z_move", "can_dynamax", "can_mega_evolve", ), ) battle = PseudoBattle([], [], False, False, False) player_pkg.Battle = PseudoBattle assert player.choose_move(battle).message == "/choose default" battle.available_switches.append(Pokemon(species="ponyta")) assert player.choose_move(battle).message == "/choose switch ponyta" battle.available_moves.append(Move("protect")) assert player.choose_move(battle).message in { "/choose move protect", "/choose switch ponyta", } battle.available_moves.append(Move("quickattack")) assert player.choose_move(battle).message in { "/choose move protect", "/choose switch ponyta", "/choose move quickattack", } battle.available_moves.append(Move("flamethrower")) assert player.choose_move(battle).message in { "/choose move protect", "/choose switch ponyta", "/choose move quickattack", "/choose move flamethrower", } assert {player.choose_move(battle).message for _ in range(500)} == { "/choose move protect", "/choose switch ponyta", "/choose move quickattack", "/choose move flamethrower", } player_pkg.Battle = ( Battle # this is in case a test runner shares memory between tests )
def test_powerherb_ends_move_preparation(): mon = Pokemon(species="roserade") mon.item = "powerherb" mon._prepare("solarbeam", "talonflame") assert mon.preparing mon._end_item("powerherb") assert not mon.preparing
def test_simple_heuristics_player_estimate_matchup(): player = SimpleHeuristicsPlayer(start_listening=False) dragapult = Pokemon(species="dragapult") assert player._estimate_matchup(dragapult, dragapult) == 0 gengar = Pokemon(species="gengar") assert player._estimate_matchup( dragapult, gengar) == -player._estimate_matchup(gengar, dragapult) assert player._estimate_matchup(dragapult, gengar) == player.SPEED_TIER_COEFICIENT mamoswine = Pokemon(species="mamoswine") assert (player._estimate_matchup(dragapult, mamoswine) == -1 + player.SPEED_TIER_COEFICIENT) dragapult._set_hp("100/100") mamoswine._set_hp("50/100") assert (player._estimate_matchup(dragapult, mamoswine) == -1 + player.SPEED_TIER_COEFICIENT + player.HP_FRACTION_COEFICIENT / 2)
def test_simple_heuristics_player_stat_estimation(): player = SimpleHeuristicsPlayer(start_listening=False) mon = Pokemon(species="charizard") assert player._stat_estimation(mon, "spe") == 236 mon._boost("spe", 2) assert player._stat_estimation(mon, "spe") == 472 mon._boost("atk", -1) assert player._stat_estimation(mon, "atk") == 136
def test_pokemon_moves(): mon = Pokemon(species="charizard") mon._moved("flamethrower") assert "flamethrower" in mon.moves mon._moved("struggle") assert "struggle" not in mon.moves assert not mon.preparing assert not mon.must_recharge
def test_single_orders(): move = Move("flamethrower") assert BattleOrder(move).message == "/choose move flamethrower" assert BattleOrder(move, mega=True).message == "/choose move flamethrower mega" assert BattleOrder( move, z_move=True).message == "/choose move flamethrower zmove" mon = Pokemon(species="charizard") assert BattleOrder(mon).message == "/choose switch charizard"
def test_choose_move(queue_get_mock): player = CustomEnvPlayer( player_configuration=player_configuration, server_configuration=server_configuration, start_listening=False, battle_format="gen7randombattles", ) battle = Battle("bat1", player.username, player.logger) battle._available_moves = {Move("flamethrower")} assert player.choose_move(battle) == "/choose move flamethrower" battle._available_moves = {Pokemon(species="charizard")} assert player.choose_move(battle) == "/choose switch charizard"
def test_protect_counter_interactions(): mon = Pokemon(species="xerneas") mon._moved("protect", failed=False) assert mon.protect_counter == 1 mon._start_effect("feint") assert mon.protect_counter == 0 mon._moved("protect", failed=False) mon._moved("protect", failed=False) assert mon.protect_counter == 2 mon._moved("geomancy", failed=False) assert mon.protect_counter == 0
def get_pokemon(self, identifier: str, force_self_team: bool = False, details: str = "") -> Pokemon: """Returns the Pokemon object corresponding to given identifier. Can force to return object from the player's team if force_self_team is True. If the Pokemon object does not exist, it will be created. Details can be given, which is necessary to initialize alternate forms (eg. alolan pokemons) properly. :param identifier: The identifier to use to retrieve the pokemon. :type identifier: str :param force_self_team: Wheter to force returning a Pokemon from the player's team. Defaults to False. :type details: str, optional :param details: Detailled information about the pokemon. Defaults to ''. :type force_self_team: bool, optional, defaults to False :return: The corresponding pokemon object. :rtype: Pokemon :raises AssertionError: If the team has more than 6 pokemons. """ is_mine = identifier[:2] == self._player_role if identifier[3] != " ": identifier = identifier[:2] + identifier[3:] species = identifier[5:] if details: species = details.split(", ")[0] else: species = identifier[4:] if is_mine or force_self_team: team: Dict[str, Pokemon] = self.team else: team: Dict[str, Pokemon] = self.opponent_team if identifier in team: return team[identifier] else: try: assert len(team) < 6 except AssertionError: self.logger.critical(team, identifier) raise Exception team[identifier] = Pokemon(species=species) return team[identifier]
def test_pokemon_as_strs(): mon = Pokemon(species="charizard") assert str(mon) == mon.__str__() == mon.__repr__() assert str( mon) == "charizard (pokemon object) [Active: False, Status: None]" mon._active = True assert str( mon) == "charizard (pokemon object) [Active: True, Status: None]" mon._set_hp_status("100/100 slp") assert str(mon) == "charizard (pokemon object) [Active: True, Status: SLP]" mon._cure_status() assert mon.status is None mon._cure_status() assert mon.status is None
def test_double_orders(): move = BattleOrder(Move("selfdestruct"), move_target=2) mon = BattleOrder(Pokemon(species="lugia")) assert (DoubleBattleOrder( move, mon).message == "/choose move selfdestruct 2, switch lugia") assert (DoubleBattleOrder( mon, move).message == "/choose switch lugia, move selfdestruct 2") assert DoubleBattleOrder(mon).message == "/choose switch lugia, default" assert (DoubleBattleOrder( None, move).message == "/choose move selfdestruct 2, default") assert DoubleBattleOrder().message == "/choose default" orders = [move, mon] both = { order.message for order in DoubleBattleOrder.join_orders(orders, orders) } first = { order.message for order in DoubleBattleOrder.join_orders(orders, []) } second = { order.message for order in DoubleBattleOrder.join_orders([], orders) } none = {order.message for order in DoubleBattleOrder.join_orders([], [])} assert both == { "/choose move selfdestruct 2, switch lugia", "/choose switch lugia, move selfdestruct 2", } assert first == { "/choose move selfdestruct 2, default", "/choose switch lugia, default", } assert second == { "/choose move selfdestruct 2, default", "/choose switch lugia, default", } assert none == {"/choose default"}
def test_dynamax(): logger = MagicMock() battle = Battle("tag", "username", logger) battle._player_role = "p1" hydreigon = Pokemon(species="hydreigon") hydreigon._active = True battle._team = {"p1: Hydreigon": hydreigon} assert battle.active_pokemon.is_dynamaxed is not True battle._parse_message(["", "-start", "p1: Hydreigon", "dynamax"]) assert battle.active_pokemon.is_dynamaxed assert battle.dynamax_turns_left == 3 battle._parse_message(["", "-end", "p1: Hydreigon", "dynamax"]) assert not battle.active_pokemon.is_dynamaxed assert battle.dynamax_turns_left is None assert not battle.can_dynamax
def get_pokemon(self, identifier: str, force_self_team: bool = False) -> Pokemon: """Returns the Pokemon object corresponding to given identifier. Can force to return object from the player's team if force_self_team is True. If the Pokemon object does not exist, it will be created. :param identifier: The identifier to use to retrieve the pokemon. :type identifier: str :param force_self_team: Wheter to force returning a Pokemon from the player's team. Defaults to False. :type force_self_team: bool, optional, defaults to False :return: The corresponding pokemon object. :rtype: Pokemon :raises AssertionError: If the team has more than 6 pokemons. """ is_mine = identifier[:2] == self._player_role if identifier[3] != " ": identifier = identifier[:2] + identifier[3:] species = identifier[5:] species = identifier[4:] if is_mine or force_self_team: team: Dict[str, Pokemon] = self.team else: team: Dict[str, Pokemon] = self.opponent_team if identifier in team: return team[identifier] else: try: assert len(team) < 6 except AssertionError: self.logger.critical(team, identifier) raise Exception team[identifier] = Pokemon(species=species) return team[identifier]
def test_reward_computing_helper(): player = CustomEnvPlayer( player_configuration=player_configuration, server_configuration=server_configuration, start_listening=False, battle_format="gen7randombattles", ) battle_1 = Battle("bat1", player.username, player.logger) battle_2 = Battle("bat2", player.username, player.logger) battle_3 = Battle("bat3", player.username, player.logger) battle_4 = Battle("bat4", player.username, player.logger) assert ( player.reward_computing_helper( battle_1, fainted_value=0, hp_value=0, number_of_pokemons=4, starting_value=0, status_value=0, victory_value=1, ) == 0 ) battle_1._won = True assert ( player.reward_computing_helper( battle_1, fainted_value=0, hp_value=0, number_of_pokemons=4, starting_value=0, status_value=0, victory_value=1, ) == 1 ) assert ( player.reward_computing_helper( battle_2, fainted_value=0, hp_value=0, number_of_pokemons=4, starting_value=0.5, status_value=0, victory_value=5, ) == -0.5 ) battle_2._won = False assert ( player.reward_computing_helper( battle_2, fainted_value=0, hp_value=0, number_of_pokemons=4, starting_value=0, status_value=0, victory_value=5, ) == -5 ) battle_3._team = {i: Pokemon(species="slaking") for i in range(4)} battle_3._opponent_team = {i: Pokemon(species="slowbro") for i in range(3)} battle_3._team[0].status = Status["FRZ"] battle_3._team[1]._current_hp = 100 battle_3._team[1]._max_hp = 200 battle_3._opponent_team[0].status = Status["FNT"] battle_3._opponent_team[1].status = Status["FNT"] # Opponent: two fainted, one full hp opponent # You: one half hp mon, one frozen mon assert ( player.reward_computing_helper( battle_3, fainted_value=2, hp_value=3, number_of_pokemons=4, starting_value=0, status_value=0.25, victory_value=100, ) == 2.25 ) battle_3._won = True assert ( player.reward_computing_helper( battle_3, fainted_value=2, hp_value=3, number_of_pokemons=4, starting_value=0, status_value=0.25, victory_value=100, ) == 100 ) battle_4._team, battle_4._opponent_team = battle_3._opponent_team, battle_3._team assert ( player.reward_computing_helper( battle_4, fainted_value=2, hp_value=3, number_of_pokemons=4, starting_value=0, status_value=0.25, victory_value=100, ) == -2.25 )
def _register_teampreview_pokemon(self, player: str, details: str): if player != self._player_role: mon = Pokemon(details=details) self._teampreview_opponent_team.add(mon)