def test_boosting_moves(): """Test boosting moves work properly.""" swords_dance = BoostingMove(**MOVE_DATA["swordsdance"]) leer = BoostingMove(**MOVE_DATA["leer"]) spinda = Pokemon(name="spinda", moves=["nuzzle", "inferno"]) charizard_target = Pokemon(name="charizard", moves=["synthesis", "recover"]) # Increase own stats swords_dance.apply_boosts(spinda, charizard_target) assert spinda.boosts["atk"] == 2 # Cannot increase own stats beyond +6 for _ in range(10): swords_dance.apply_boosts(spinda, charizard_target) assert spinda.boosts["atk"] == 6 # Decrease opponents' stats leer.apply_boosts(spinda, charizard_target) assert charizard_target.boosts["def"] == -1 # Cannot decrease stats beyond -6 for _ in range(10): leer.apply_boosts(spinda, charizard_target) assert charizard_target.boosts["def"] == -6
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 ev_validation(): """Validate provided EVs.""" # Negative EVs try: evs = {"hp": -1, "atk": 1} Pokemon(name="exploud", moves=["tackle"], evs=evs) assert False except AttributeError: pass # Too many EVs try: evs = {"hp": 500, "atk": 1} Pokemon(name="exploud", moves=["tackle"], evs=evs) assert False except AttributeError: pass # Decimal EVs try: evs = {"hp": 500.5, "atk": 1} Pokemon(name="exploud", moves=["tackle"], evs=evs) assert False except AttributeError: pass
def status_dmg_test(): """Test Status Damage applied correctly.""" pkmn = Pokemon(name="spinda", moves=["tackle", "watergun"], level=50) pkmn.status = BRN_STATUS pkmn.apply_status_damage() assert pkmn.max_hp > pkmn.current_hp
def test_infer_speed_investment(): """Test how we infer speed.""" magikarp = Pokemon(name="magikarp", moves=["tackle"]) spinda = Pokemon(name="spinda", moves=["tackle"]) ppgs1 = PokemonPlayerGameState() ppgs2 = PokemonPlayerGameState() gamestate = {} gamestate["team"] = [] gamestate["active"] = magikarp opp_gamestate_dict = {} opp_gamestate_dict["team"] = [] opp_gamestate_dict["active"] = spinda opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict) ppgs1.update_gamestate(gamestate, opp_gamestate) ppgs2.update_gamestate(opp_gamestate_dict, anonymize_gamestate_helper(gamestate)) new_info = {} new_info["type"] = "ATTACK" new_info["move"] = MOVE_DATA["tackle"] new_info["attacker"] = "player2" new_info["defender"] = "player1" new_info["pct_damage"] = 27 new_info["damage"] = 46 new_info["atk_poke"] = "spinda" new_info["def_poke"] = "magikarp" new_info = [new_info] * 2 test_infer_speed_faster(ppgs2, new_info) test_infer_speed_slower(ppgs1, new_info)
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 range_no_params(): """Range Calculations with no parameters.""" dsc = DamageStatCalc() attacker = Pokemon(name="spinda", moves=["tackle"]) defender = Pokemon(name="spinda", moves=["tackle"]) move = generate_move(MOVE_DATA["tackle"]) params = {} params["atk"] = {} params["def"] = {} params["hp"] = {} dmg_range = dsc.calculate_range(move, attacker, defender, params) assert dmg_range[0] == 16 assert dmg_range[1] == 20 attacker = Pokemon(name="floatzel", moves=["watergun"]) move = generate_move(MOVE_DATA['watergun']) dmg_range = dsc.calculate_range(move, attacker, defender, params) assert dmg_range[0] == 21 assert dmg_range[1] == 26 defender = attacker dmg_range = dsc.calculate_range(move, attacker, defender, params) assert dmg_range[0] == 10 assert dmg_range[1] == 13
def test_calculate_damage(): """Test that damage is calculated properly.""" tackle = BaseMove(**MOVE_DATA["tackle"]) exploud = Pokemon(name="exploud", moves=["return"]) floatzel = Pokemon(name="floatzel", moves=["shadowball"]) damage, _ = tackle.calculate_damage(exploud, floatzel, True) assert damage == 78
def test_ohko_move(): """Test that OHKO moves do target's current HP worth of damage.""" sheer_cold = OHKOMove(**MOVE_DATA["sheercold"]) exploud = Pokemon(name="exploud", moves=["return"]) floatzel = Pokemon(name="floatzel", moves=["shadowball"]) assert sheer_cold.calculate_damage(exploud, floatzel)[0] == floatzel.current_hp
def test_possible_moves(): """Make sure possible_moves works properly.""" pkmn = Pokemon(name="spinda", moves=["tackle", "watergun"], level=50) poke_can_switch, moves = pkmn.possible_moves() assert poke_can_switch assert moves assert len(moves) == 2
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_lockedmove_vs(): """Make sure lockedmove is handled properly.""" dragonite = Pokemon(name="dragonite", moves=["outrage"]) aggron_target = Pokemon(name="aggron", moves=["recover"]) outrage = VolatileStatusMove(**MOVE_DATA["outrage"]) outrage.apply_volatile_status(dragonite, aggron_target) assert dragonite.volatile_status assert "lockedmove" in dragonite.volatile_status assert dragonite.volatile_status["lockedmove"]["move"] == outrage assert dragonite.volatile_status["lockedmove"]["counter"] == 0
def update_speed_inference(self, turn_info, my_id): """ Infer speed information from the turn info. Args: turn_info (dict): Information on a single event of that turn. my_id (str): Name corresponding to the "attacker" or "defender" values of this dict. """ # Moves are different priority, no inference can be made if turn_info[0]["move"]["priority"] != turn_info[1]["move"]["priority"]: return # We're outsped; ie: we're slower opp_poke = turn_info[0]["atk_poke"] outspeed = False if turn_info[0]["attacker"] == my_id: # We outspeed; ie: we're faster opp_poke = turn_info[0]["def_poke"] outspeed = True if opp_poke not in self.opp_gamestate["investment"]: self.opp_gamestate["investment"][opp_poke] = {} if "spe" not in self.opp_gamestate["investment"][opp_poke]: # Slowest possible opponent's pokemon min_speed = Pokemon(name=opp_poke, moves=["tackle"], nature="brave").speed # Fastest possible opponent's pokemon max_speed = Pokemon(name=opp_poke, moves=["tackle"], evs={ "spe": 252 }, nature="jolly").speed self.opp_gamestate["investment"][opp_poke]["spe"] = [ min_speed, max_speed ] if outspeed: if self.opp_gamestate["investment"][opp_poke]["spe"][1] > \ self.gamestate["active"].speed: # Update maximum speed to our speed if necessary self.opp_gamestate["investment"][opp_poke]["spe"][1] = \ self.gamestate["active"].speed else: if self.opp_gamestate["investment"][opp_poke]["spe"][0] < \ self.gamestate["active"].speed: # Update minimum speed to our speed, if necessary self.opp_gamestate["investment"][opp_poke]["spe"][0] = \ self.gamestate["active"].speed
def test_effective_stats(): """Test that stat boosts are calculated effectively.""" pkmn1 = Pokemon(name="spinda", moves=["tackle"], level=50) # Positive boosts pkmn1.boosts["atk"] = 1 assert pkmn1.effective_stat("atk") == 80 * 1.5 pkmn1.boosts["atk"] = 6 assert pkmn1.effective_stat("atk") == 80 * 4 pkmn1.boosts["atk"] = -1 assert pkmn1.effective_stat("atk") == int(80 * 2 / 3) pkmn1.boosts["atk"] = -6 assert pkmn1.effective_stat("atk") == 80 * 2 / 8
def test_calculate_modifier(): """Test that modifier is calculated properly.""" tackle = BaseMove(**MOVE_DATA["tackle"]) exploud = Pokemon(name="exploud", moves=["return"]) floatzel = Pokemon(name="floatzel", moves=["shadowball"]) gengar = Pokemon(name="gengar", moves=["tackle"]) regirock = Pokemon(name="regirock", moves=["selfdestruct"]) assert tackle.calculate_modifier(exploud, gengar) == 0 # No Effect assert tackle.calculate_modifier(exploud, floatzel) == 1.5 # STAB assert tackle.calculate_modifier(floatzel, regirock) == 0.5 # Not Very Effective assert tackle.calculate_modifier(exploud, regirock) == 0.75 # Multiply together
def move_validation(): """Validate the moves provided.""" # Invalid moves provided try: Pokemon(name="exploud", moves=["doot"], level=100) assert False except AttributeError: pass # No moves provided try: Pokemon(name="exploud", moves=[], level=100) assert False except AttributeError: pass
def test_primary_vs(): """Test that primary volatileStatus is set properly.""" chimchar_confuse = Pokemon(name="chimchar", moves=["confuseray"]) chimchar_uproar = Pokemon(name="spinda", moves=["uproar"], nature="timid") confuse_ray = VolatileStatusMove(**MOVE_DATA["confuseray"]) uproar = VolatileStatusMove(**MOVE_DATA["uproar"]) confuse_ray.apply_volatile_status(chimchar_confuse, chimchar_uproar) uproar.apply_volatile_status(chimchar_uproar, chimchar_confuse) # Check volatile status applied assert chimchar_uproar.volatile_status assert chimchar_uproar.volatile_status["confusion"] == 0 assert chimchar_uproar.volatile_status["uproar"] == 0
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_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 test_opp_gamestate(): """Test that opponent's gamestate is updated properly.""" spinda = Pokemon(name="spinda", moves=["tackle"]) ppgs1 = PokemonPlayerGameState() ppgs2 = PokemonPlayerGameState() gamestate = {} gamestate["team"] = [] gamestate["active"] = spinda opp_gamestate = anonymize_gamestate_helper(gamestate) # Update the gamestate ppgs1.update_gamestate(gamestate, opp_gamestate) ppgs2.update_gamestate(gamestate, opp_gamestate) # Gamestate updating happens properly. assert ppgs1.opp_gamestate["data"] assert not ppgs1.opp_gamestate["data"]["team"] assert ppgs1.opp_gamestate["data"]["active"]["name"] == "spinda" turn_info = {} turn_info["type"] = "ATTACK" turn_info["attacker"] = "player2" turn_info["move"] = spinda.moves[0] turn_info["pct_damage"] = 28 turn_info["def_poke"] = "spinda" turn_info["atk_poke"] = "spinda" turn_info = [turn_info] # Give new info ppgs1.new_info(turn_info, "player1") # New info is stored properly assert len(ppgs1.opp_gamestate["moves"]["spinda"]) == 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_substitute_vs(): """Make sure substitute is handled properly.""" exploud = Pokemon(name="exploud", moves=["substitute"]) spinda_target = Pokemon(name="spinda", moves=["tackle"]) substitute = VolatileStatusMove(**MOVE_DATA["substitute"]) sub_hp = floor(exploud.max_hp / 4.0) substitute.apply_volatile_status(exploud, spinda_target) # Make sure volatile status applied assert exploud.volatile_status assert "substitute" in exploud.volatile_status # Make sure substitute calculated properly. assert exploud.volatile_status["substitute"] == sub_hp assert exploud.max_hp == sub_hp + exploud.current_hp
def pokemon_validation(): """Validate pokemon choice.""" # Invalid pokemon choice try: Pokemon(name="doot", moves=["tackle"], level=100) assert False except AttributeError: pass
def test_getitem_validation(): """Test using the [] operator on this object.""" pkmn1 = Pokemon(name="spinda", moves=["tackle"], level=50) assert pkmn1.level == pkmn1["level"] assert pkmn1.name == pkmn1["name"] assert pkmn1.base_stats["atk"] == pkmn1["baseStats"]["atk"] assert pkmn1.base_stats["atk"] == pkmn1["base_stats"]["atk"]
def nature_validation(): """Validate nature properly handled.""" # Invalid nature try: Pokemon(name="exploud", moves=["tackle"], nature="doot") assert False except AttributeError: pass
def init_bppa(): """Initialize the Player for these tests.""" spinda = Pokemon(name="spinda", moves=["tackle", "frustration"]) magikarp = Pokemon(name="magikarp", moves=["tackle"]) exploud = Pokemon(name="exploud", moves=["tackle"]) gamestate = {} gamestate["team"] = [exploud, magikarp] gamestate["active"] = spinda opp_gamestate = anonymize_gamestate_helper(gamestate) # Update the gamestate bppa = BasicPlanningPokemonAgent(tier="pu", team=[spinda]) bppa.update_gamestate(gamestate, opp_gamestate) bppa.init_opp_gamestate(opp_gamestate["team"], opp_gamestate["active"]) return bppa
def range_status(): """Test damage range with burn status.""" dsc = DamageStatCalc() params = {} params["atk"] = {} params["def"] = {} params["hp"] = {} move = generate_move(MOVE_DATA["tackle"]) attacker = Pokemon(name="spinda", moves=["tackle"]) defender = Pokemon(name="spinda", moves=["tackle"]) attacker.status = BRN_STATUS dmg_range = dsc.calculate_range(move, attacker, defender, params) assert dmg_range[0] == 8 assert dmg_range[1] == 10
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_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]