def test_engine_player_2ndary_stat_changes(): """Test for secondary stat changes to self.""" spinda = Pokemon(name="spinda", moves=["poweruppunch"]) scyther_target = Pokemon(name="scyther", moves=["synthesis"]) player1 = PokemonAgent([spinda]) player2 = PokemonAgent([scyther_target]) player_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) # Assert that spinda's attack is +1 p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player1"]["active"].boosts["atk"] == 1 # Assert that stat doesn't get higher than +6 for _ in range(10): p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player1"]["active"].boosts["atk"] == 6 # Test that if on damage happens, stat drops don't # Ex: Fighting move to Ghost-type gengar_target = Pokemon(name="gengar", moves=["synthesis"]) player3 = PokemonAgent([gengar_target]) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player3) p_eng.run_single_turn(player_move, player_move, player1, player3) assert p_eng.game_state["player1"]["active"].boosts["atk"] == 0
def test_engine_opp_2ndary_stat_change(): """Test secondary effects that involve opponent's stat changes.""" spinda = Pokemon(name="spinda", moves=["lowsweep"]) scyther_target = Pokemon(name="scyther", moves=["synthesis"]) player1 = PokemonAgent([spinda]) player2 = PokemonAgent([scyther_target]) player_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) # Assert Spinda_target's at -2 SpD p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player2"]["active"].boosts["spe"] == -1 # Assert that stat doesn't get lower than -6 for _ in range(10): p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player2"]["active"].boosts["spe"] == -6 # Test that if on damage happens, stat drops don't # Ex: Poison Move to Steel-Type gengar_target = Pokemon(name="gengar", moves=["synthesis"]) player3 = PokemonAgent([gengar_target]) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player3) p_eng.run_single_turn(player_move, player_move, player1, player3) assert p_eng.game_state["player2"]["active"].boosts["spe"] == 0
def test_run_multiple_moves(): """Test running a game with multiple moves.""" exploud = Pokemon(name="exploud", moves=["shadowball"]) spinda = Pokemon(name="spinda", moves=["watergun", "tackle", "thundershock"]) player1 = PokemonAgent([exploud]) player2 = PokemonAgent([spinda]) p_eng = PokemonEngine() p_eng.run(player1, player2)
def test_run_infinite(): """Test running a game where it'll go on forever.""" exploud1 = Pokemon(name="exploud", moves=["shadowball"]) exploud2 = Pokemon(name="exploud", moves=["shadowball"]) player1 = PokemonAgent([exploud1]) player2 = PokemonAgent([exploud2]) p_eng = PokemonEngine(turn_limit=500) p_eng.run(player1, player2) # We got to the turn limit assert p_eng.game_state["num_turns"] > p_eng.turn_limit
def test_battle_posn_one(): """Test battle position functions work.""" magikarp = Pokemon(name="magikarp", moves=["tackle"]) magikarp_opp = Pokemon(name="magikarp", moves=["tackle"]) pa1 = PokemonAgent([magikarp]) gamestate = {} gamestate["team"] = [] gamestate["active"] = magikarp opp_gamestate_dict = {} opp_gamestate_dict["team"] = [] opp_gamestate_dict["active"] = magikarp_opp opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict) pa1.update_gamestate(gamestate, opp_gamestate) assert pa1.calc_position() == 1 assert pa1.calc_opp_position() == 1 assert pa1.battle_position() == 1 # We're now in a bad position magikarp.current_hp = 1 pa1.update_gamestate(gamestate, opp_gamestate) assert pa1.calc_position() < 0.1 assert pa1.calc_opp_position() == 1 assert pa1.battle_position() < 1 # Now we're in a better position. magikarp.current_hp = magikarp.max_hp / 2 magikarp_opp.current_hp = 1 opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict) pa1.update_gamestate(gamestate, opp_gamestate) assert pa1.calc_position() == 0.5 assert pa1.calc_opp_position() < 0.1 assert pa1.battle_position() > 1
def test_poison_dmg(): """Test that poison damage is applied.""" exploud = Pokemon(name="exploud", moves=["synthesis"]) exploud_psn = Pokemon(name="exploud", moves=["synthesis"]) exploud_psn.status = PSN_STATUS player1 = PokemonAgent([exploud]) player2 = PokemonAgent([exploud_psn]) player_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player2"]["active"].current_hp == \ int(1+7*p_eng.game_state["player2"]["active"].max_hp/8)
def test_run(): """Test running of a pokemon game.""" exploud = Pokemon(name="exploud", moves=["return"]) floatzel = Pokemon(name="floatzel", moves=["shadowball"]) player1 = PokemonAgent([exploud]) player2 = PokemonAgent([floatzel]) p_eng = PokemonEngine() outcome = p_eng.run(player1, player2) assert outcome == 1 assert p_eng.game_state["player1"]["active"] is not None assert not p_eng.game_state["player1"]["team"] assert p_eng.game_state["player2"]["active"] is None assert not p_eng.game_state["player2"]["team"]
def add_agents(self): """Add the agents to this model.""" for conf in self.config: conf_tr = TeamReader(prefix=conf["team_file"]) conf_tr.process_files() conf_team = conf_tr.teams[0] for _ in range(int(self.num_players * conf["proportion"])): pkmn_agent = None if conf["agent_class"] == "basic": pkmn_agent = PokemonAgent( team=conf_team ) pkmn_agent.type = conf["agent_type"] elif conf["agent_class"] == "basicplanning": pkmn_agent = BasicPlanningPokemonAgent( tier=conf["agent_tier"], team=conf_team ) pkmn_agent.type = conf["agent_type"] else: raise RuntimeError("Invalid agent_class: {}".format(conf["agent_class"])) self.ladder.add_player(pkmn_agent)
def test_heal(): """Test that healing works properly.""" ivysaur = Pokemon(name="ivysaur", moves=["synthesis"]) floatzel = Pokemon(name="floatzel", moves=["watergun"]) player1 = PokemonAgent([ivysaur]) player1_move = ("ATTACK", 0) player2 = PokemonAgent([floatzel]) player2_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) p_eng.run_single_turn(player1_move, player2_move, player1, player2) # Healed assert p_eng.game_state["player1"]["active"].current_hp == \ p_eng.game_state["player1"]["active"].max_hp
def test_lockedmove_vs(): """Make sure lockedmove is handled properly.""" player1 = PokemonAgent([Pokemon(name="dragonite", moves=["outrage"])]) player2 = PokemonAgent([Pokemon(name="aggron", moves=["recover"])]) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) player_move = ("ATTACK", 0) p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player1"]["active"].volatile_status assert "lockedmove" in p_eng.game_state["player1"][ "active"].volatile_status assert p_eng.game_state["player1"]["active"].volatile_status["lockedmove"][ "counter"] == 1 assert p_eng.game_state["player1"]["active"].volatile_status["lockedmove"]["move"] == \ p_eng.game_state["player1"]["active"].moves[0]
def test_run_multiple_pokemon(): """Test running a game with multiple pokemon.""" exploud = Pokemon(name="exploud", moves=["synthesis"], level=100) spinda1 = Pokemon(name="spinda", moves=["watergun"], level=5) spinda2 = Pokemon(name="spinda", moves=["tackle"], level=5) magikarp = Pokemon(name="magikarp", moves=["thundershock"], level=5) player1 = PokemonAgent([exploud]) player2 = PokemonAgent([spinda1, spinda2, magikarp]) p_eng = PokemonEngine(turn_limit=500) p_eng.run(player1, player2) assert len(player1.game_state.opp_gamestate["moves"]["magikarp"]) == 1 assert player1.game_state.opp_gamestate["moves"]["magikarp"][0][ "name"] == "Thunder Shock" assert len(player1.game_state.opp_gamestate["moves"]["spinda"]) == 2
def test_engine_2ndary_status(): """Status effects as secondary effect.""" spinda = Pokemon(name="spinda", moves=["nuzzle", "inferno"]) charizard_target = Pokemon(name="charizard", moves=["synthesis", "recover"]) player1 = PokemonAgent([spinda]) player2 = PokemonAgent([charizard_target]) player_first_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) # Assert that Muk gets paralyzed p_eng.run_single_turn(player_first_move, player_first_move, player1, player2) assert p_eng.game_state["player2"]["active"].status == PAR_STATUS # Assert that if there's another status effect, it # cannot be overwritten charizard_target.status = PSN_STATUS p_eng.initialize_battle(player1, player2) p_eng.run_single_turn(player_first_move, player_first_move, player1, player2) assert p_eng.game_state["player2"]["active"].status == PSN_STATUS # Assert that the type immunities are respected charizard_target.status = None player_second_move = ("ATTACK", 1) p_eng.initialize_battle(player1, player2) p_eng.run_single_turn(player_second_move, player_second_move, player1, player2) assert p_eng.game_state["player2"]["active"].status is None # Assert that if no damage, no status effect trapinch_target = Pokemon(name="trapinch", moves=["synthesis"]) player3 = PokemonAgent([trapinch_target]) p_eng.initialize_battle(player1, player3) p_eng.run_single_turn(player_first_move, player_first_move, player1, player3) assert p_eng.game_state["player2"]["active"].status is None
def test_accuracy(): """Test to check for accuracy being taken into account.""" # < 0.5% chance of all the hydro pumps hitting num_misses = 0 for _ in range(12): exploud = Pokemon(name="exploud", moves=["hydropump"]) floatzel = Pokemon(name="floatzel", moves=["hydropump"]) player1 = PokemonAgent([exploud]) player2 = PokemonAgent([floatzel]) player_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) for turn_info in p_eng.run_single_turn(player_move, player_move, player1, player2)[1]: if not turn_info["move_hits"]: num_misses += 1 assert num_misses > 0 # All the flamethrowers should hit num_misses = 0 for _ in range(50): exploud = Pokemon(name="exploud", moves=["flamethrower"]) floatzel = Pokemon(name="floatzel", moves=["flamethrower"]) player1 = PokemonAgent([exploud]) player2 = PokemonAgent([floatzel]) player_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) for turn_info in p_eng.run_single_turn(player_move, player_move, player1, player2)[1]: if not turn_info["move_hits"]: num_misses += 1 assert num_misses == 0
def test_switch_faint(): """Test that switch_faint() picks a valid pokemon.""" exploud = Pokemon(name="exploud", moves=["tackle"]) pa1 = PokemonAgent([exploud]) gamestate = {} gamestate["team"] = [exploud, exploud, exploud] gamestate["active"] = None opp_gamestate = anonymize_gamestate_helper(gamestate) pa1.update_gamestate(gamestate, opp_gamestate) val = pa1.switch_faint() assert val in range(3)
def test_toxic_dmg(): """Toxic damage applied correctly.""" exploud = Pokemon(name="exploud", moves=["synthesis"]) exploud_tox = Pokemon(name="exploud", moves=["shadowball"]) exploud_tox.status = TOX_STATUS player1 = PokemonAgent([exploud]) player2 = PokemonAgent([exploud_tox]) player_move = ("ATTACK", 0) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) # First turn is 15/16 p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player2"]["active"].current_hp == \ int(1+15*p_eng.game_state["player2"]["active"].max_hp/16) prev_hp = p_eng.game_state["player2"]["active"].current_hp # Second turn is ~13/16 p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player2"]["active"].current_hp == \ int(1 + prev_hp - 2*p_eng.game_state["player2"]["active"].max_hp/16)
def test_substitute_vs(): """Make sure substitute is handled properly.""" player1 = PokemonAgent([Pokemon(name="exploud", moves=["substitute"])]) player2 = PokemonAgent([ Pokemon(name="spinda", moves=["tackle"]), Pokemon(name="magikarp", moves=["tackle"]) ]) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) sub_hp = floor(p_eng.game_state["player1"]["active"].max_hp / 4.0) player_move = ("ATTACK", 0) player2_move = ("SWITCH", 0) p_eng.run_single_turn(player_move, player2_move, player1, player2) assert p_eng.game_state["player1"]["active"].volatile_status assert "substitute" in p_eng.game_state["player1"][ "active"].volatile_status assert p_eng.game_state["player1"]["active"].volatile_status[ "substitute"] == sub_hp assert p_eng.game_state["player1"]["active"].max_hp == \ sub_hp + p_eng.game_state["player1"]["active"].current_hp
def test_primary_vs(): """Test that primary volatileStatus is set properly.""" player1 = PokemonAgent([Pokemon(name="spinda", moves=["confuseray"])]) player2 = PokemonAgent( [Pokemon(name="spinda", moves=["uproar"], nature="timid")]) p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) player_move = ("ATTACK", 0) p_eng.run_single_turn(player_move, player_move, player1, player2) # Check volatile status applied assert p_eng.game_state["player2"]["active"].volatile_status assert p_eng.game_state["player2"]["active"].volatile_status[ "confusion"] == 0 assert p_eng.game_state["player2"]["active"].volatile_status["uproar"] == 1 # Increment counter p_eng.run_single_turn(player_move, player_move, player1, player2) assert p_eng.game_state["player2"]["active"].volatile_status assert p_eng.game_state["player2"]["active"].volatile_status[ "confusion"] == 1 assert p_eng.game_state["player2"]["active"].volatile_status["uproar"] == 2
def test_vs_switch(): """Test that volatile statuses are reset upon switching.""" player1 = PokemonAgent([ Pokemon(name="exploud", moves=["tackle"]), Pokemon(name="spinda", moves=["tackle"]) ]) player2 = PokemonAgent([ Pokemon(name="floatzel", moves=["tackle"]), Pokemon(name="magikarp", moves=["tackle"]) ]) # Initialize the game p_eng = PokemonEngine() p_eng.initialize_battle(player1, player2) p_eng.game_state["player1"]["active"].volatile_status["test"] = True p_eng.game_state["player2"]["active"].volatile_status["test"] = True # Run the switch player_move = ("SWITCH", 0) p_eng.run_single_turn(player_move, player_move, player1, player2) # Check volatile status reset assert not p_eng.game_state["player1"]["team"][0].volatile_status assert not p_eng.game_state["player2"]["team"][0].volatile_status
def test_battle_posn_multiple(): """Test that battle position functions work with multiple pokemon.""" magikarp = Pokemon(name="magikarp", moves=["tackle"]) magikarp_opp = Pokemon(name="magikarp", moves=["tackle"]) spinda = Pokemon(name="spinda", moves=["tackle"]) pa1 = PokemonAgent([magikarp, spinda, spinda]) gamestate = {} gamestate["team"] = [spinda, spinda] gamestate["active"] = magikarp opp_gamestate_dict = {} opp_gamestate_dict["team"] = [spinda] opp_gamestate_dict["active"] = magikarp_opp opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict) # Everything maximum HP pa1.update_gamestate(gamestate, opp_gamestate) assert pa1.calc_position() == 3 assert pa1.calc_opp_position() == 2 assert pa1.battle_position() == 1.5 # Good position, opponent has low HP magikarp_opp.current_hp = 1 opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict) pa1.update_gamestate(gamestate, opp_gamestate) assert pa1.calc_position() == 3 assert pa1.calc_opp_position() < 2 assert pa1.calc_opp_position() > 1 assert pa1.battle_position() > 1.5 assert pa1.battle_position() < 3 # Bad position, we have low HP magikarp_opp.current_hp = magikarp_opp.max_hp magikarp.current_hp = 1 opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict) pa1.update_gamestate(gamestate, opp_gamestate) assert pa1.calc_position() < 3 assert pa1.calc_position() > 2 assert pa1.calc_opp_position() == 2 assert pa1.battle_position() < 1.5 assert pa1.calc_position() > 1
def test_make_move(): """Test that make_move is outputting valid info.""" spinda = Pokemon( name="spinda", moves=["tackle", "watergun", "thundershock", "shadowball"]) magikarp = Pokemon(name="magikarp", moves=["tackle"]) pa1 = PokemonAgent([spinda, magikarp, magikarp, magikarp]) # Set player's gamestate pa1.game_state.gamestate = {} pa1.game_state.gamestate["team"] = [magikarp, magikarp, magikarp] pa1.game_state.gamestate["active"] = spinda move_type, val = pa1.make_move() assert move_type in ["SWITCH", "ATTACK"] if move_type == "SWITCH": # Switch to magikarp assert val in range(3) else: # Picks one of 4 moves assert val in range(4)