def setUp(self): self.state = State( Side( Pokemon.from_state_pokemon_dict(StatePokemon("pikachu", 100).to_dict()), { "rattata": Pokemon.from_state_pokemon_dict(StatePokemon("rattata", 100).to_dict()), "charmander": Pokemon.from_state_pokemon_dict(StatePokemon("charmander", 100).to_dict()), "squirtle": Pokemon.from_state_pokemon_dict(StatePokemon("squirtle", 100).to_dict()), "bulbasaur": Pokemon.from_state_pokemon_dict(StatePokemon("bulbasaur", 100).to_dict()), "pidgey": Pokemon.from_state_pokemon_dict(StatePokemon("pidgey", 100).to_dict()) }, (0, 0), defaultdict(lambda: 0) ), Side( Pokemon.from_state_pokemon_dict(StatePokemon("pikachu", 100).to_dict()), { "rattata": Pokemon.from_state_pokemon_dict(StatePokemon("rattata", 100).to_dict()), "charmander": Pokemon.from_state_pokemon_dict(StatePokemon("charmander", 100).to_dict()), "squirtle": Pokemon.from_state_pokemon_dict(StatePokemon("squirtle", 100).to_dict()), "bulbasaur": Pokemon.from_state_pokemon_dict(StatePokemon("bulbasaur", 100).to_dict()), "pidgey": Pokemon.from_state_pokemon_dict(StatePokemon("pidgey", 100).to_dict()) }, (0, 0), defaultdict(lambda: 0) ), None, None, False ) self.mutator = StateMutator(self.state)
def create_state(self): user_active = TransposePokemon.from_state_pokemon_dict( self.user.active.to_dict()) user_reserve = dict() for mon in self.user.reserve: user_reserve[mon.name] = TransposePokemon.from_state_pokemon_dict( mon.to_dict()) opponent_active = TransposePokemon.from_state_pokemon_dict( self.opponent.active.to_dict()) opponent_reserve = dict() for mon in self.opponent.reserve: opponent_reserve[ mon.name] = TransposePokemon.from_state_pokemon_dict( mon.to_dict()) user = Side(user_active, user_reserve, copy(self.user.wish), copy(self.user.side_conditions)) opponent = Side(opponent_active, opponent_reserve, copy(self.opponent.wish), copy(self.opponent.side_conditions)) state = State(user, opponent, self.weather, self.field, self.trick_room) return state
def to_object(self): user_active = TransposePokemon.from_state_pokemon_dict( self.user.active.to_dict()) user_reserve = dict() for mon in self.user.reserve: user_reserve[mon.name] = TransposePokemon.from_state_pokemon_dict( mon.to_dict()) opponent_active = TransposePokemon.from_state_pokemon_dict( self.opponent.active.to_dict()) opponent_reserve = dict() for mon in self.opponent.reserve: opponent_reserve[ mon.name] = TransposePokemon.from_state_pokemon_dict( mon.to_dict()) user = Side(user_active, user_reserve, copy(self.user.side_conditions), self.user.trapped) opponent = Side(opponent_active, opponent_reserve, copy(self.opponent.side_conditions), self.opponent.trapped) state = State(user, opponent, self.weather, self.field, self.trick_room, self.force_switch, self.wait) return state
def to_object(self): # the bot knows the disabled status of it's own moves - this only needs to be done for the opponent self.opponent.lock_moves() user_active = TransposePokemon.from_state_pokemon_dict( self.user.active.to_dict()) user_reserve = dict() for mon in self.user.reserve: user_reserve[mon.name] = TransposePokemon.from_state_pokemon_dict( mon.to_dict()) opponent_active = TransposePokemon.from_state_pokemon_dict( self.opponent.active.to_dict()) opponent_reserve = dict() for mon in self.opponent.reserve: opponent_reserve[ mon.name] = TransposePokemon.from_state_pokemon_dict( mon.to_dict()) user = Side(user_active, user_reserve, copy(self.user.side_conditions), self.user.trapped) opponent = Side(opponent_active, opponent_reserve, copy(self.opponent.side_conditions), self.opponent.trapped) state = State(user, opponent, self.weather, self.field, self.trick_room, self.force_switch, self.wait) return state
def test_state_serialization_and_loading_results_in_the_same_state(self): state_json = {'self': {'active': {'id': 'tornadustherian', 'level': 100, 'hp': 0, 'maxhp': 0, 'ability': 'regenerator', 'item': 'fightiniumz', 'attack': 212, 'defense': 197, 'special-attack': 319, 'special-defense': 216, 'speed': 375, 'attack_boost': -1, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'taunt', 'disabled': False, 'current_pp': 32}, {'id': 'hurricane', 'disabled': False, 'current_pp': 16}, {'id': 'focusblast', 'disabled': False, 'current_pp': 8}, {'id': 'defog', 'disabled': False, 'current_pp': 24}], 'types': ['flying'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'reserve': {'greninja': {'id': 'greninja', 'level': 100, 'hp': 285, 'maxhp': 285, 'ability': 'battlebond', 'item': 'choicespecs', 'attack': 203, 'defense': 171, 'special-attack': 305, 'special-defense': 178, 'speed': 377, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'surf', 'disabled': False, 'current_pp': 24}, {'id': 'darkpulse', 'disabled': False, 'current_pp': 24}, {'id': 'icebeam', 'disabled': False, 'current_pp': 16}, {'id': 'watershuriken', 'disabled': False, 'current_pp': 32}], 'types': ['water', 'dark'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'mawile': {'id': 'mawile', 'level': 100, 'hp': 261.0, 'maxhp': 261, 'ability': 'intimidate', 'item': 'mawilite', 'attack': 295, 'defense': 206, 'special-attack': 131, 'special-defense': 146, 'speed': 180, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'suckerpunch', 'disabled': False, 'current_pp': 8}, {'id': 'playrough', 'disabled': False, 'current_pp': 16}, {'id': 'thunderpunch', 'disabled': False, 'current_pp': 24}, {'id': 'firefang', 'disabled': False, 'current_pp': 24}], 'types': ['steel', 'fairy'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'ferrothorn': {'id': 'ferrothorn', 'level': 100, 'hp': 352.0, 'maxhp': 352, 'ability': 'ironbarbs', 'item': 'leftovers', 'attack': 224, 'defense': 299, 'special-attack': 144, 'special-defense': 364, 'speed': 68, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'spikes', 'disabled': False, 'current_pp': 32}, {'id': 'leechseed', 'disabled': False, 'current_pp': 16}, {'id': 'knockoff', 'disabled': False, 'current_pp': 32}, {'id': 'gyroball', 'disabled': False, 'current_pp': 8}], 'types': ['grass', 'steel'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'heatran': {'id': 'heatran', 'level': 100, 'hp': 385, 'maxhp': 385, 'ability': 'flashfire', 'item': 'leftovers', 'attack': 194, 'defense': 248, 'special-attack': 296, 'special-defense': 332, 'speed': 201, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'taunt', 'disabled': False, 'current_pp': 32}, {'id': 'magmastorm', 'disabled': False, 'current_pp': 8}, {'id': 'earthpower', 'disabled': False, 'current_pp': 16}, {'id': 'toxic', 'disabled': False, 'current_pp': 16}], 'types': ['fire', 'steel'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'garchomp': {'id': 'garchomp', 'level': 100, 'hp': 379, 'maxhp': 379, 'ability': 'roughskin', 'item': 'rockyhelmet', 'attack': 296, 'defense': 317, 'special-attack': 176, 'special-defense': 206, 'speed': 282, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'stealthrock', 'disabled': False, 'current_pp': 32}, {'id': 'earthquake', 'disabled': False, 'current_pp': 16}, {'id': 'toxic', 'disabled': False, 'current_pp': 16}, {'id': 'roar', 'disabled': False, 'current_pp': 32}], 'types': ['dragon', 'ground'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}}, 'wish': (0, 0), 'futuresight': (0, 0), 'side_conditions': {'toxic_count': 0, 'tailwind': 0, 'stealthrock': 0, 'spikes': 0, 'stickyweb': 0, 'toxicspikes': 0, 'reflect': 0, 'lightscreen': 0, 'auroraveil': 0}}, 'opponent': {'active': {'id': 'landorustherian', 'level': 100, 'hp': 319.0, 'maxhp': 319, 'ability': 'intimidate', 'item': 'choicescarf', 'attack': 389, 'defense': 216, 'special-attack': 223.63636363636363, 'special-defense': 197, 'speed': 309.1, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'earthquake', 'disabled': False, 'current_pp': 16}, {'id': 'uturn', 'disabled': False, 'current_pp': 32}, {'id': 'stealthrock', 'disabled': False, 'current_pp': 32}, {'id': 'defog', 'disabled': False, 'current_pp': 24}, {'id': 'stoneedge', 'disabled': False, 'current_pp': 8}], 'types': ['ground', 'flying'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'reserve': {'ferrothorn': {'id': 'ferrothorn', 'level': 100, 'hp': 352.0, 'maxhp': 352, 'ability': 'ironbarbs', 'item': 'leftovers', 'attack': 224, 'defense': 304, 'special-attack': 158.4, 'special-defense': 326, 'speed': 69.09090909090908, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'leechseed', 'disabled': False, 'current_pp': 16}, {'id': 'gyroball', 'disabled': False, 'current_pp': 8}, {'id': 'stealthrock', 'disabled': False, 'current_pp': 32}, {'id': 'powerwhip', 'disabled': False, 'current_pp': 16}], 'types': ['grass', 'steel'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'rotomwash': {'id': 'rotomwash', 'level': 100, 'hp': 304.0, 'maxhp': 304, 'ability': 'levitate', 'item': 'leftovers', 'attack': 150.9090909090909, 'defense': 330.0, 'special-attack': 246, 'special-defense': 250, 'speed': 222, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'hydropump', 'disabled': False, 'current_pp': 8}, {'id': 'voltswitch', 'disabled': False, 'current_pp': 32}, {'id': 'willowisp', 'disabled': False, 'current_pp': 24}, {'id': 'defog', 'disabled': False, 'current_pp': 24}], 'types': ['electric', 'water'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'mawile': {'id': 'mawile', 'level': 100, 'hp': 303.0, 'maxhp': 303, 'ability': 'intimidate', 'item': 'leftovers', 'attack': 295.90000000000003, 'defense': 206, 'special-attack': 132.72727272727272, 'special-defense': 148, 'speed': 136, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'playrough', 'disabled': False, 'current_pp': 16}, {'id': 'ironhead', 'disabled': False, 'current_pp': 24}, {'id': 'suckerpunch', 'disabled': False, 'current_pp': 8}, {'id': 'swordsdance', 'disabled': False, 'current_pp': 32}], 'types': ['steel', 'fairy'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'greninja': {'id': 'greninja', 'level': 100, 'hp': 285.0, 'maxhp': 285, 'ability': 'protean', 'item': 'choicescarf', 'attack': 205.45454545454544, 'defense': 170, 'special-attack': 305, 'special-defense': 179, 'speed': 377.3, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'icebeam', 'disabled': False, 'current_pp': 16}, {'id': 'gunkshot', 'disabled': False, 'current_pp': 8}, {'id': 'uturn', 'disabled': False, 'current_pp': 32}, {'id': 'hydropump', 'disabled': False, 'current_pp': 8}], 'types': ['water', 'dark'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}, 'scolipede': {'id': 'scolipede', 'level': 100, 'hp': 261.0, 'maxhp': 261, 'ability': 'speedboost', 'item': 'wateriumz', 'attack': 328.90000000000003, 'defense': 214, 'special-attack': 132.72727272727272, 'special-defense': 175, 'speed': 323, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'accuracy_boost': 1, 'evasion_boost': 1, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'swordsdance', 'disabled': False, 'current_pp': 32}, {'id': 'earthquake', 'disabled': False, 'current_pp': 16}, {'id': 'megahorn', 'disabled': False, 'current_pp': 16}, {'id': 'poisonjab', 'disabled': False, 'current_pp': 32}], 'types': ['bug', 'poison'], 'nature': 'serious', 'evs': (85, 85, 85, 85, 85, 85)}}, 'wish': (0, 0), 'futuresight': (0, 0), 'side_conditions': {'toxic_count': 0, 'tailwind': 0, 'reflect': 0, 'lightscreen': 0, 'auroraveil': 0, 'stealthrock': 0, 'spikes': 0, 'stickyweb': 0, 'toxicspikes': 0}}, 'weather': 1, 'field': 2, 'trickroom': 3} state = State.from_dict(state_json) # str(state) gives a string representing the state-dict new_state_dict = eval(str(state)) self.assertEqual(state_json, new_state_dict)
def setUp(self): self.state = State( Side( Pokemon.from_state_pokemon_dict(StatePokemon("raichu", 73).to_dict()), { "xatu": Pokemon.from_state_pokemon_dict(StatePokemon("xatu", 81).to_dict()), "starmie": Pokemon.from_state_pokemon_dict(StatePokemon("starmie", 81).to_dict()), "gyarados": Pokemon.from_state_pokemon_dict(StatePokemon("gyarados", 81).to_dict()), "dragonite": Pokemon.from_state_pokemon_dict(StatePokemon("dragonite", 81).to_dict()), "hitmonlee": Pokemon.from_state_pokemon_dict(StatePokemon("hitmonlee", 81).to_dict()), }, defaultdict(lambda: 0), False ), Side( Pokemon.from_state_pokemon_dict(StatePokemon("aromatisse", 81).to_dict()), { "yveltal": Pokemon.from_state_pokemon_dict(StatePokemon("yveltal", 73).to_dict()), "slurpuff": Pokemon.from_state_pokemon_dict(StatePokemon("slurpuff", 73).to_dict()), "victini": Pokemon.from_state_pokemon_dict(StatePokemon("victini", 73).to_dict()), "toxapex": Pokemon.from_state_pokemon_dict(StatePokemon("toxapex", 73).to_dict()), "bronzong": Pokemon.from_state_pokemon_dict(StatePokemon("bronzong", 73).to_dict()), }, defaultdict(lambda: 0), False ), None, None, False, False, False ) self.state.self.active.moves = [ {constants.ID: 'tackle', constants.DISABLED: False}, {constants.ID: 'charm', constants.DISABLED: False}, {constants.ID: 'growl', constants.DISABLED: False}, {constants.ID: 'stringshot', constants.DISABLED: False}, ] self.state.opponent.active.moves = [ {constants.ID: 'tackle', constants.DISABLED: False}, {constants.ID: 'charm', constants.DISABLED: False}, {constants.ID: 'growl', constants.DISABLED: False}, {constants.ID: 'stringshot', constants.DISABLED: False}, ]
def setUp(self): self.blastoise = Pokemon.from_state_pokemon_dict( StatePokemon("blastoise", 100).to_dict()) self.venusaur = Pokemon.from_state_pokemon_dict( StatePokemon("venusaur", 100).to_dict()) self.state = State( Side(self.blastoise, dict(), (0, 0), defaultdict(lambda: 0)), Side(self.venusaur, dict(), (0, 0), defaultdict(lambda: 0)), None, None, None)
class TestGetAllOptions(unittest.TestCase): def setUp(self): self.state = State( Side( Pokemon.from_state_pokemon_dict(StatePokemon("raichu", 73).to_dict()), { "xatu": Pokemon.from_state_pokemon_dict(StatePokemon("xatu", 81).to_dict()), "starmie": Pokemon.from_state_pokemon_dict(StatePokemon("starmie", 81).to_dict()), "gyarados": Pokemon.from_state_pokemon_dict(StatePokemon("gyarados", 81).to_dict()), "dragonite": Pokemon.from_state_pokemon_dict(StatePokemon("dragonite", 81).to_dict()), "hitmonlee": Pokemon.from_state_pokemon_dict(StatePokemon("hitmonlee", 81).to_dict()), }, (0, 0), defaultdict(lambda: 0) ), Side( Pokemon.from_state_pokemon_dict(StatePokemon("aromatisse", 81).to_dict()), { "yveltal": Pokemon.from_state_pokemon_dict(StatePokemon("yveltal", 73).to_dict()), "slurpuff": Pokemon.from_state_pokemon_dict(StatePokemon("slurpuff", 73).to_dict()), "victini": Pokemon.from_state_pokemon_dict(StatePokemon("victini", 73).to_dict()), "toxapex": Pokemon.from_state_pokemon_dict(StatePokemon("toxapex", 73).to_dict()), "bronzong": Pokemon.from_state_pokemon_dict(StatePokemon("bronzong", 73).to_dict()), }, (0, 0), defaultdict(lambda: 0) ), None, None, False ) self.state.self.active.moves = [ {constants.ID: 'tackle', constants.DISABLED: False}, {constants.ID: 'charm', constants.DISABLED: False}, {constants.ID: 'growl', constants.DISABLED: False}, {constants.ID: 'stringshot', constants.DISABLED: False}, ] self.state.opponent.active.moves = [ {constants.ID: 'tackle', constants.DISABLED: False}, {constants.ID: 'charm', constants.DISABLED: False}, {constants.ID: 'growl', constants.DISABLED: False}, {constants.ID: 'stringshot', constants.DISABLED: False}, ] def test_returns_all_options_in_normal_situation(self): expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_partiallytrapped_removes_switch_options_for_bot(self): self.state.self.active.volatile_status.add(constants.PARTIALLY_TRAPPED) expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_partiallytrapped_removes_switch_options_for_opponent(self): self.state.opponent.active.volatile_status.add(constants.PARTIALLY_TRAPPED) expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_bot_with_shadowtag_prevents_switch_options_for_opponent(self): self.state.self.active.ability = 'shadowtag' expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_opponent_with_shadowtag_prevents_switch_options(self): self.state.opponent.active.ability = 'shadowtag' expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_ghost_type_can_switch_out_versus_shadow_tag(self): self.state.opponent.active.ability = 'shadowtag' self.state.self.active.types = ['ghost'] expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_non_steel_can_switch_out_versus_magnetpull(self): self.state.opponent.active.ability = 'magnetpull' self.state.self.active.types = ['ghost'] expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_shedshell_can_always_switch(self): self.state.opponent.active.ability = 'shadowtag' self.state.self.active.item = 'shedshell' expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_bot_can_switch_as_flying_type_versus_arenatrap(self): self.state.opponent.active.ability = 'arenatrap' self.state.self.active.types = ['flying'] expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_airballoon_allows_holder_to_switch(self): self.state.opponent.active.ability = 'arenatrap' self.state.self.active.types = ['normal'] self.state.self.active.item = 'airballoon' expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_arenatrap_traps_non_grounded(self): self.state.opponent.active.ability = 'arenatrap' expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_steel_type_cannot_switch_out_versus_magnetpull(self): self.state.opponent.active.ability = 'magnetpull' self.state.self.active.types = ['steel'] expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_returns_only_switches_for_user_and_nothing_for_opponent_when_user_active_is_dead(self): expected_options = ( [ 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ constants.DO_NOTHING_MOVE ] ) self.state.self.active.hp = 0 options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_returns_nothing_for_user_when_opponent_active_is_dead(self): self.state.opponent.active.hp = 0 expected_user_options = [ constants.DO_NOTHING_MOVE ] options = self.state.get_all_options() self.assertEqual(expected_user_options, options[0]) def test_double_faint_returns_correct_decisions(self): self.state.self.active.hp = 0 self.state.opponent.active.hp = 0 expected_options = ( [ 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ], ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_double_faint_with_no_reserve_pokemon_returns_correct_decisions(self): self.state.self.active.hp = 0 self.state.opponent.active.hp = 0 for mon in self.state.self.reserve.values(): mon.hp = 0 expected_options = ( [ constants.DO_NOTHING_MOVE ], [ 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ], ) options = self.state.get_all_options() self.assertEqual(expected_options, options)
def setUp(self): self.state_json = { 'self': { 'active': { 'id': 'keldeo', 'level': 100, 'hp': 323, 'maxhp': 344, 'ability': 'justified', 'item': None, 'baseStats': { 'hp': 91, 'attack': 72, 'defense': 90, 'special-attack': 129, 'special-defense': 90, 'speed': 108 }, 'attack': 201, 'defense': 237, 'special-attack': 315, 'special-defense': 237, 'speed': 273, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 1, 'special_defense_boost': 1, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'calmmind', 'disabled': False, 'current_pp': 31 }, { 'id': 'hydropump', 'disabled': False, 'current_pp': 7 }, { 'id': 'secretsword', 'disabled': False, 'current_pp': 15 }, { 'id': 'taunt', 'disabled': False, 'current_pp': 32 }], 'types': ['water', 'fighting'], 'canMegaEvo': False }, 'reserve': { 'landorustherian': { 'id': 'landorustherian', 'level': 100, 'hp': 319, 'maxhp': 340, 'ability': 'intimidate', 'item': None, 'baseStats': { 'hp': 89, 'attack': 145, 'defense': 90, 'special-attack': 105, 'special-defense': 80, 'speed': 91 }, 'attack': 347, 'defense': 237, 'special-attack': 267, 'special-defense': 217, 'speed': 239, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'stealthrock', 'disabled': False, 'current_pp': 32 }, { 'id': 'earthquake', 'disabled': False, 'current_pp': 16 }, { 'id': 'explosion', 'disabled': False, 'current_pp': 8 }, { 'id': 'swordsdance', 'disabled': False, 'current_pp': 32 }], 'types': ['ground', 'flying'], 'canMegaEvo': False }, 'tornadustherian': { 'id': 'tornadustherian', 'level': 100, 'hp': 362, 'maxhp': 320, 'ability': 'regenerator', 'item': None, 'baseStats': { 'hp': 79, 'attack': 100, 'defense': 80, 'special-attack': 110, 'special-defense': 90, 'speed': 121 }, 'attack': 257, 'defense': 217, 'special-attack': 277, 'special-defense': 237, 'speed': 299, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'hurricane', 'disabled': False, 'current_pp': 16 }, { 'id': 'defog', 'disabled': False, 'current_pp': 24 }, { 'id': 'knockoff', 'disabled': False, 'current_pp': 32 }, { 'id': 'uturn', 'disabled': False, 'current_pp': 32 }], 'types': ['flying'], 'canMegaEvo': False }, 'diancie': { 'id': 'diancie', 'level': 100, 'hp': 241, 'maxhp': 262, 'ability': 'clearbody', 'item': None, 'baseStats': { 'hp': 50, 'attack': 100, 'defense': 150, 'special-attack': 100, 'special-defense': 150, 'speed': 50 }, 'attack': 257, 'defense': 357, 'special-attack': 257, 'special-defense': 357, 'speed': 157, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'moonblast', 'disabled': False, 'current_pp': 24 }, { 'id': 'diamondstorm', 'disabled': False, 'current_pp': 8 }, { 'id': 'substitute', 'disabled': False, 'current_pp': 16 }, { 'id': 'endeavor', 'disabled': False, 'current_pp': 8 }], 'types': ['rock', 'fairy'], 'canMegaEvo': False }, 'victini': { 'id': 'victini', 'level': 100, 'hp': 341, 'maxhp': 362, 'ability': 'victorystar', 'item': None, 'baseStats': { 'hp': 100, 'attack': 100, 'defense': 100, 'special-attack': 100, 'special-defense': 100, 'speed': 100 }, 'attack': 257, 'defense': 257, 'special-attack': 257, 'special-defense': 257, 'speed': 257, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'vcreate', 'disabled': False, 'current_pp': 8 }, { 'id': 'boltstrike', 'disabled': False, 'current_pp': 8 }, { 'id': 'uturn', 'disabled': False, 'current_pp': 32 }, { 'id': 'finalgambit', 'disabled': False, 'current_pp': 8 }], 'types': ['psychic', 'fire'], 'canMegaEvo': False }, 'bisharp': { 'id': 'bisharp', 'level': 100, 'hp': 271, 'maxhp': 292, 'ability': 'defiant', 'item': None, 'baseStats': { 'hp': 65, 'attack': 125, 'defense': 100, 'special-attack': 60, 'special-defense': 70, 'speed': 70 }, 'attack': 307, 'defense': 257, 'special-attack': 177, 'special-defense': 197, 'speed': 197, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'knockoff', 'disabled': False, 'current_pp': 32 }, { 'id': 'ironhead', 'disabled': False, 'current_pp': 24 }, { 'id': 'suckerpunch', 'disabled': False, 'current_pp': 8 }, { 'id': 'swordsdance', 'disabled': False, 'current_pp': 32 }], 'types': ['dark', 'steel'], 'canMegaEvo': False } }, 'side_conditions': { 'tailwind': 0, 'reflect': 0, 'lightscreen': 0, 'auroraveil': 0, 'stealthrock': 0, 'spikes': 0, 'stickyweb': 0, 'toxicspikes': 0 }, 'trapped': False }, 'opponent': { 'active': { 'id': 'manaphy', 'level': 100, 'hp': 86.88, 'maxhp': 362, 'ability': 'hydration', 'item': 'Leftovers', 'baseStats': { 'hp': 100, 'attack': 100, 'defense': 100, 'special-attack': 100, 'special-defense': 100, 'speed': 100 }, 'attack': 257, 'defense': 257, 'special-attack': 257, 'special-defense': 257, 'speed': 257, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 6, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'tailglow', 'disabled': False, 'current_pp': 32 }], 'types': ['water'], 'canMegaEvo': False }, 'reserve': { 'mamoswine': { 'id': 'mamoswine', 'level': 100, 'hp': 382, 'maxhp': 382, 'ability': None, 'item': None, 'baseStats': { 'hp': 110, 'attack': 130, 'defense': 80, 'special-attack': 70, 'special-defense': 60, 'speed': 80 }, 'attack': 317, 'defense': 217, 'special-attack': 197, 'special-defense': 177, 'speed': 217, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [], 'types': ['ice', 'ground'], 'canMegaEvo': False }, 'alakazam': { 'id': 'alakazam', 'level': 100, 'hp': 272, 'maxhp': 272, 'ability': None, 'item': None, 'baseStats': { 'hp': 55, 'attack': 50, 'defense': 45, 'special-attack': 135, 'special-defense': 95, 'speed': 120 }, 'attack': 157, 'defense': 147, 'special-attack': 327, 'special-defense': 247, 'speed': 297, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [], 'types': ['psychic'], 'canMegaEvo': False }, 'stakataka': { 'id': 'stakataka', 'level': 100, 'hp': 284, 'maxhp': 284, 'ability': 'beastboost', 'item': None, 'baseStats': { 'hp': 61, 'attack': 131, 'defense': 211, 'special-attack': 53, 'special-defense': 101, 'speed': 13 }, 'attack': 319, 'defense': 479, 'special-attack': 163, 'special-defense': 259, 'speed': 83, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [], 'types': ['rock', 'steel'], 'canMegaEvo': False }, 'moltres': { 'id': 'moltres', 'level': 100, 'hp': 342, 'maxhp': 342, 'ability': None, 'item': None, 'baseStats': { 'hp': 90, 'attack': 100, 'defense': 90, 'special-attack': 125, 'special-defense': 85, 'speed': 90 }, 'attack': 257, 'defense': 237, 'special-attack': 307, 'special-defense': 227, 'speed': 237, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [], 'types': ['fire', 'flying'], 'canMegaEvo': False }, 'gliscor': { 'id': 'gliscor', 'level': 100, 'hp': 312, 'maxhp': 312, 'ability': None, 'item': None, 'baseStats': { 'hp': 75, 'attack': 95, 'defense': 125, 'special-attack': 45, 'special-defense': 75, 'speed': 95 }, 'attack': 247, 'defense': 307, 'special-attack': 147, 'special-defense': 207, 'speed': 247, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [], 'types': ['ground', 'flying'], 'canMegaEvo': False } }, 'side_conditions': { 'tailwind': 0, 'reflect': 0, 'lightscreen': 0, 'auroraveil': 0, 'stealthrock': 0, 'spikes': 0, 'stickyweb': 0, 'toxicspikes': 0 }, 'trapped': False }, 'weather': None, 'field': None, 'forceSwitch': False, 'wait': False, 'trickroom': False } self.state = State.from_dict(self.state_json)
state = State.from_dict({ 'self': { 'active': { 'id': 'greninja', 'level': 100, 'hp': 285, 'maxhp': 285, 'ability': 'battlebond', 'item': 'choicespecs', 'baseStats': { 'hp': 72, 'attack': 95, 'defense': 67, 'special-attack': 103, 'special-defense': 71, 'speed': 122 }, 'attack': 203, 'defense': 171, 'special-attack': 305, 'special-defense': 178, 'speed': 377, 'attack_boost': -1, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'surf', 'disabled': False, 'current_pp': 24 }, { 'id': 'darkpulse', 'disabled': False, 'current_pp': 24 }, { 'id': 'icebeam', 'disabled': False, 'current_pp': 16 }, { 'id': 'watershuriken', 'disabled': False, 'current_pp': 32 }], 'types': ['water', 'dark'], 'canMegaEvo': False }, 'reserve': { 'mawile': { 'id': 'mawile', 'level': 100, 'hp': 261, 'maxhp': 261, 'ability': 'intimidate', 'item': 'mawilite', 'baseStats': { 'hp': 50, 'attack': 85, 'defense': 85, 'special-attack': 55, 'special-defense': 55, 'speed': 50 }, 'attack': 295, 'defense': 206, 'special-attack': 131, 'special-defense': 146, 'speed': 180, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'suckerpunch', 'disabled': False, 'current_pp': 8 }, { 'id': 'playrough', 'disabled': False, 'current_pp': 16 }, { 'id': 'thunderpunch', 'disabled': False, 'current_pp': 24 }, { 'id': 'firefang', 'disabled': False, 'current_pp': 24 }], 'types': ['steel', 'fairy'], 'canMegaEvo': False }, 'tornadustherian': { 'id': 'tornadustherian', 'level': 100, 'hp': 299, 'maxhp': 299, 'ability': 'regenerator', 'item': 'fightiniumz', 'baseStats': { 'hp': 79, 'attack': 100, 'defense': 80, 'special-attack': 110, 'special-defense': 90, 'speed': 121 }, 'attack': 212, 'defense': 197, 'special-attack': 319, 'special-defense': 216, 'speed': 375, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'taunt', 'disabled': False, 'current_pp': 32 }, { 'id': 'hurricane', 'disabled': False, 'current_pp': 16 }, { 'id': 'focusblast', 'disabled': False, 'current_pp': 8 }, { 'id': 'defog', 'disabled': False, 'current_pp': 24 }], 'types': ['flying'], 'canMegaEvo': False }, 'ferrothorn': { 'id': 'ferrothorn', 'level': 100, 'hp': 352, 'maxhp': 352, 'ability': 'ironbarbs', 'item': 'leftovers', 'baseStats': { 'hp': 74, 'attack': 94, 'defense': 131, 'special-attack': 54, 'special-defense': 116, 'speed': 20 }, 'attack': 224, 'defense': 299, 'special-attack': 144, 'special-defense': 364, 'speed': 68, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'spikes', 'disabled': False, 'current_pp': 32 }, { 'id': 'leechseed', 'disabled': False, 'current_pp': 16 }, { 'id': 'knockoff', 'disabled': False, 'current_pp': 32 }, { 'id': 'gyroball', 'disabled': False, 'current_pp': 8 }], 'types': ['grass', 'steel'], 'canMegaEvo': False }, 'heatran': { 'id': 'heatran', 'level': 100, 'hp': 385, 'maxhp': 385, 'ability': 'flashfire', 'item': 'leftovers', 'baseStats': { 'hp': 91, 'attack': 90, 'defense': 106, 'special-attack': 130, 'special-defense': 106, 'speed': 77 }, 'attack': 194, 'defense': 248, 'special-attack': 296, 'special-defense': 332, 'speed': 201, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'taunt', 'disabled': False, 'current_pp': 32 }, { 'id': 'magmastorm', 'disabled': False, 'current_pp': 8 }, { 'id': 'earthpower', 'disabled': False, 'current_pp': 16 }, { 'id': 'toxic', 'disabled': False, 'current_pp': 16 }], 'types': ['fire', 'steel'], 'canMegaEvo': False }, 'garchomp': { 'id': 'garchomp', 'level': 100, 'hp': 379, 'maxhp': 379, 'ability': 'roughskin', 'item': 'rockyhelmet', 'baseStats': { 'hp': 108, 'attack': 130, 'defense': 95, 'special-attack': 80, 'special-defense': 85, 'speed': 102 }, 'attack': 296, 'defense': 317, 'special-attack': 176, 'special-defense': 206, 'speed': 282, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'stealthrock', 'disabled': False, 'current_pp': 32 }, { 'id': 'earthquake', 'disabled': False, 'current_pp': 16 }, { 'id': 'toxic', 'disabled': False, 'current_pp': 16 }, { 'id': 'roar', 'disabled': False, 'current_pp': 32 }], 'types': ['dragon', 'ground'], 'canMegaEvo': False } }, 'side_conditions': { 'toxic_count': 0 }, 'trapped': False }, 'opponent': { 'active': { 'id': 'landorustherian', 'level': 100, 'hp': 319.0, 'maxhp': 319, 'ability': 'intimidate', 'item': 'choicescarf', 'baseStats': { 'hp': 89, 'attack': 145, 'defense': 90, 'special-attack': 105, 'special-defense': 80, 'speed': 91 }, 'attack': 389, 'defense': 216, 'special-attack': 223.63636363636363, 'special-defense': 197, 'speed': 309.1, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'earthquake', 'disabled': False, 'current_pp': 16 }, { 'id': 'stoneedge', 'disabled': False, 'current_pp': 16 }, { 'id': 'uturn', 'disabled': False, 'current_pp': 32 }, { 'id': 'stealthrock', 'disabled': False, 'current_pp': 32 }, { 'id': 'defog', 'disabled': False, 'current_pp': 24 }], 'types': ['ground', 'flying'], 'canMegaEvo': False }, 'reserve': { 'magearna': { 'id': 'magearna', 'level': 100, 'hp': 363.0, 'maxhp': 363, 'ability': 'soulheart', 'item': 'assaultvest', 'baseStats': { 'hp': 80, 'attack': 95, 'defense': 115, 'special-attack': 130, 'special-defense': 115, 'speed': 65 }, 'attack': 226, 'defense': 266, 'special-attack': 325.6, 'special-defense': 322, 'speed': 159.09090909090907, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'fleurcannon', 'disabled': False, 'current_pp': 8 }, { 'id': 'voltswitch', 'disabled': False, 'current_pp': 32 }, { 'id': 'thunderbolt', 'disabled': False, 'current_pp': 24 }, { 'id': 'icebeam', 'disabled': False, 'current_pp': 16 }], 'types': ['steel', 'fairy'], 'canMegaEvo': False }, 'gliscor': { 'id': 'gliscor', 'level': 100, 'hp': 352.0, 'maxhp': 352, 'ability': 'poisonheal', 'item': 'toxicorb', 'baseStats': { 'hp': 75, 'attack': 95, 'defense': 125, 'special-attack': 45, 'special-defense': 75, 'speed': 95 }, 'attack': 226, 'defense': 299, 'special-attack': 114.54545454545453, 'special-defense': 211, 'speed': 279.40000000000003, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'earthquake', 'disabled': False, 'current_pp': 16 }, { 'id': 'roost', 'disabled': False, 'current_pp': 16 }, { 'id': 'toxic', 'disabled': False, 'current_pp': 16 }, { 'id': 'stealthrock', 'disabled': False, 'current_pp': 32 }], 'types': ['ground', 'flying'], 'canMegaEvo': False }, 'clefable': { 'id': 'clefable', 'level': 100, 'hp': 394.0, 'maxhp': 394, 'ability': 'magicguard', 'item': 'leftovers', 'baseStats': { 'hp': 95, 'attack': 70, 'defense': 73, 'special-attack': 95, 'special-defense': 90, 'speed': 60 }, 'attack': 160.0, 'defense': 269.5, 'special-attack': 226, 'special-defense': 217, 'speed': 156, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'moonblast', 'disabled': False, 'current_pp': 24 }, { 'id': 'softboiled', 'disabled': False, 'current_pp': 16 }, { 'id': 'wish', 'disabled': False, 'current_pp': 16 }, { 'id': 'calmmind', 'disabled': False, 'current_pp': 32 }], 'types': ['fairy'], 'canMegaEvo': False }, 'tapubulu': { 'id': 'tapubulu', 'level': 100, 'hp': 343.0, 'maxhp': 343, 'ability': 'grassysurge', 'item': 'leftovers', 'baseStats': { 'hp': 70, 'attack': 130, 'defense': 115, 'special-attack': 85, 'special-defense': 95, 'speed': 75 }, 'attack': 296, 'defense': 268, 'special-attack': 206.0, 'special-defense': 289, 'speed': 186, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'hornleech', 'disabled': False, 'current_pp': 16 }, { 'id': 'superpower', 'disabled': False, 'current_pp': 8 }, { 'id': 'woodhammer', 'disabled': False, 'current_pp': 24 }, { 'id': 'stoneedge', 'disabled': False, 'current_pp': 8 }], 'types': ['grass', 'fairy'], 'canMegaEvo': False }, 'gyarados': { 'id': 'gyarados', 'level': 100, 'hp': 331.0, 'maxhp': 331, 'ability': 'moxie', 'item': 'flyiniumz', 'baseStats': { 'hp': 95, 'attack': 125, 'defense': 79, 'special-attack': 60, 'special-defense': 100, 'speed': 81 }, 'attack': 349, 'defense': 194, 'special-attack': 141.8181818181818, 'special-defense': 237, 'speed': 287.1, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{ 'id': 'waterfall', 'disabled': False, 'current_pp': 24 }, { 'id': 'dragondance', 'disabled': False, 'current_pp': 32 }, { 'id': 'earthquake', 'disabled': False, 'current_pp': 16 }, { 'id': 'bounce', 'disabled': False, 'current_pp': 8 }], 'types': ['water', 'flying'], 'canMegaEvo': False } }, 'side_conditions': { 'toxic_count': 0 }, 'trapped': False }, 'weather': None, 'field': None, 'trickroom': False, 'forceSwitch': False, 'wait': False })
'canMegaEvo': False } }, 'side_conditions': { 'toxic_count': 0 }, 'trapped': False }, 'weather': None, 'field': None, 'trickroom': False, 'forceSwitch': False, 'wait': False } # second = {'self': {'active': {'id': 'audino', 'level': 81, 'hp': 299, 'maxhp': 299, 'ability': 'regenerator', 'baseStats': {'hp': 103, 'attack': 60, 'defense': 86, 'special-attack': 60, 'special-defense': 86, 'speed': 50}, 'attack': 144, 'defense': 186, 'special-attack': 144, 'special-defense': 186, 'speed': 128, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'healbell', 'disabled': False, 'current_pp': 8}, {'id': 'protect', 'disabled': False, 'current_pp': 16}, {'id': 'wish', 'disabled': False, 'current_pp': 16}, {'id': 'hypervoice', 'disabled': False, 'current_pp': 16}], 'types': ['normal']}, 'reserve': {'heatran': {'id': 'heatran', 'level': 75, 'hp': 0, 'maxhp': 260, 'ability': 'flashfire', 'baseStats': {'hp': 91, 'attack': 90, 'defense': 106, 'special-attack': 130, 'special-defense': 106, 'speed': 77}, 'attack': 179, 'defense': 203, 'special-attack': 239, 'special-defense': 203, 'speed': 159, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'roar', 'disabled': False, 'current_pp': 32}, {'id': 'stealthrock', 'disabled': False, 'current_pp': 32}, {'id': 'earthpower', 'disabled': False, 'current_pp': 16}, {'id': 'lavaplume', 'disabled': False, 'current_pp': 24}], 'types': ['fire', 'steel']}, 'omastar': {'id': 'omastar', 'level': 81, 'hp': 246, 'maxhp': 246, 'ability': 'swiftswim', 'baseStats': {'hp': 70, 'attack': 60, 'defense': 125, 'special-attack': 115, 'special-defense': 70, 'speed': 55}, 'attack': 144, 'defense': 249, 'special-attack': 233, 'special-defense': 160, 'speed': 136, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'scald', 'disabled': False, 'current_pp': 24}, {'id': 'shellsmash', 'disabled': False, 'current_pp': 24}, {'id': 'earthpower', 'disabled': False, 'current_pp': 16}, {'id': 'icebeam', 'disabled': False, 'current_pp': 16}], 'types': ['rock', 'water']}, 'alomomola': {'id': 'alomomola', 'level': 77, 'hp': 381, 'maxhp': 381, 'ability': 'regenerator', 'baseStats': {'hp': 165, 'attack': 75, 'defense': 80, 'special-attack': 40, 'special-defense': 45, 'speed': 65}, 'attack': 160, 'defense': 168, 'special-attack': 106, 'special-defense': 114, 'speed': 145, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'knockoff', 'disabled': False, 'current_pp': 32}, {'id': 'wish', 'disabled': False, 'current_pp': 16}, {'id': 'toxic', 'disabled': False, 'current_pp': 16}, {'id': 'scald', 'disabled': False, 'current_pp': 24}], 'types': ['water']}, 'hawlucha': {'id': 'hawlucha', 'level': 75, 'hp': 105, 'maxhp': 241, 'ability': 'unburden', 'baseStats': {'hp': 78, 'attack': 92, 'defense': 75, 'special-attack': 74, 'special-defense': 63, 'speed': 118}, 'attack': 182, 'defense': 156, 'special-attack': 155, 'special-defense': 138, 'speed': 221, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'swordsdance', 'disabled': False, 'current_pp': 32}, {'id': 'stoneedge', 'disabled': False, 'current_pp': 8}, {'id': 'roost', 'disabled': False, 'current_pp': 16}, {'id': 'highjumpkick', 'disabled': False, 'current_pp': 16}], 'types': ['fighting', 'flying']}, 'swalot': {'id': 'swalot', 'level': 83, 'hp': 129, 'maxhp': 302, 'ability': 'stickyhold', 'baseStats': {'hp': 100, 'attack': 73, 'defense': 83, 'special-attack': 73, 'special-defense': 83, 'speed': 55}, 'attack': 169, 'defense': 185, 'special-attack': 169, 'special-defense': 185, 'speed': 139, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'icebeam', 'disabled': False, 'current_pp': 16}, {'id': 'encore', 'disabled': False, 'current_pp': 8}, {'id': 'yawn', 'disabled': False, 'current_pp': 16}, {'id': 'sludgebomb', 'disabled': False, 'current_pp': 16}], 'types': ['poison']}}, 'side_conditions': {'stealthrock': 0, 'spikes': 0}, 'trapped': False}, 'opponent': {'active': {'id': 'zekrom', 'level': 73, 'hp': 202.16, 'maxhp': 266, 'ability': 'teravolt', 'baseStats': {'hp': 100, 'attack': 150, 'defense': 120, 'special-attack': 120, 'special-defense': 100, 'speed': 90}, 'attack': 261, 'defense': 218, 'special-attack': 218, 'special-defense': 188, 'speed': 174, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'boltstrike', 'disabled': False, 'current_pp': 8}, {'id': 'substitute', 'disabled': False, 'current_pp': 16}], 'types': ['dragon', 'electric']}, 'reserve': {'rotomfrost': {'id': 'rotomfrost', 'level': 83, 'hp': 199.29000000000002, 'maxhp': 219, 'ability': 'levitate', 'baseStats': {'hp': 50, 'attack': 65, 'defense': 107, 'special-attack': 105, 'special-defense': 107, 'speed': 86}, 'attack': 156, 'defense': 225, 'special-attack': 222, 'special-defense': 225, 'speed': 190, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'voltswitch', 'disabled': False, 'current_pp': 32}], 'types': ['electric', 'ice']}, 'bibarel': {'id': 'bibarel', 'level': 83, 'hp': 0, 'maxhp': 267, 'ability': None, 'baseStats': {'hp': 79, 'attack': 85, 'defense': 60, 'special-attack': 55, 'special-defense': 60, 'speed': 71}, 'attack': 189, 'defense': 147, 'special-attack': 139, 'special-defense': 147, 'speed': 166, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'return', 'disabled': False, 'current_pp': 32}], 'types': ['normal', 'water']}, 'passimian': {'id': 'passimian', 'level': 83, 'hp': 193.28, 'maxhp': 302, 'ability': None, 'baseStats': {'hp': 100, 'attack': 120, 'defense': 90, 'special-attack': 40, 'special-defense': 60, 'speed': 80}, 'attack': 247, 'defense': 197, 'special-attack': 114, 'special-defense': 147, 'speed': 180, 'attack_boost': 0, 'defense_boost': 0, 'special_attack_boost': 0, 'special_defense_boost': 0, 'speed_boost': 0, 'status': None, 'volatileStatus': [], 'moves': [{'id': 'uturn', 'disabled': False, 'current_pp': 32}], 'types': ['fighting']}}, 'side_conditions': {'stealthrock': 0, 'spikes': 0}, 'trapped': False}, 'weather': None, 'field': None, 'forceSwitch': False, 'wait': False} state = State.from_dict(first) mutator = StateMutator(state) instruction = get_all_state_instructions(mutator, 'flareblitz', 'nastyplot') scores = get_payoff_matrix(mutator, depth=2) df = pd.Series(scores).unstack() averages = df.mean(axis=1) safest = pick_safest(scores) pass
class TestGetAllOptions(unittest.TestCase): def setUp(self): self.state = State( Side( Pokemon.from_state_pokemon_dict(StatePokemon("raichu", 73).to_dict()), { "xatu": Pokemon.from_state_pokemon_dict(StatePokemon("xatu", 81).to_dict()), "starmie": Pokemon.from_state_pokemon_dict(StatePokemon("starmie", 81).to_dict()), "gyarados": Pokemon.from_state_pokemon_dict(StatePokemon("gyarados", 81).to_dict()), "dragonite": Pokemon.from_state_pokemon_dict(StatePokemon("dragonite", 81).to_dict()), "hitmonlee": Pokemon.from_state_pokemon_dict(StatePokemon("hitmonlee", 81).to_dict()), }, defaultdict(lambda: 0), False ), Side( Pokemon.from_state_pokemon_dict(StatePokemon("aromatisse", 81).to_dict()), { "yveltal": Pokemon.from_state_pokemon_dict(StatePokemon("yveltal", 73).to_dict()), "slurpuff": Pokemon.from_state_pokemon_dict(StatePokemon("slurpuff", 73).to_dict()), "victini": Pokemon.from_state_pokemon_dict(StatePokemon("victini", 73).to_dict()), "toxapex": Pokemon.from_state_pokemon_dict(StatePokemon("toxapex", 73).to_dict()), "bronzong": Pokemon.from_state_pokemon_dict(StatePokemon("bronzong", 73).to_dict()), }, defaultdict(lambda: 0), False ), None, None, False, False, False ) self.state.self.active.moves = [ {constants.ID: 'tackle', constants.DISABLED: False}, {constants.ID: 'charm', constants.DISABLED: False}, {constants.ID: 'growl', constants.DISABLED: False}, {constants.ID: 'stringshot', constants.DISABLED: False}, ] self.state.opponent.active.moves = [ {constants.ID: 'tackle', constants.DISABLED: False}, {constants.ID: 'charm', constants.DISABLED: False}, {constants.ID: 'growl', constants.DISABLED: False}, {constants.ID: 'stringshot', constants.DISABLED: False}, ] def test_returns_all_options_in_normal_situation(self): expected_options = ( [ 'tackle', 'charm', 'growl', 'stringshot', 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'tackle', 'charm', 'growl', 'stringshot', 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ] ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_returns_only_switches_for_user_and_nothing_for_opponent_when_user_active_is_dead(self): expected_options = ( [ 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ constants.DO_NOTHING_MOVE ] ) self.state.self.active.hp = 0 options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_returns_nothing_for_user_when_opponent_active_is_dead(self): self.state.opponent.active.hp = 0 expected_user_options = [ constants.DO_NOTHING_MOVE ] options = self.state.get_all_options() self.assertEqual(expected_user_options, options[0]) def test_double_faint_returns_correct_decisions(self): self.state.self.active.hp = 0 self.state.opponent.active.hp = 0 expected_options = ( [ 'switch xatu', 'switch starmie', 'switch gyarados', 'switch dragonite', 'switch hitmonlee' ], [ 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ], ) options = self.state.get_all_options() self.assertEqual(expected_options, options) def test_double_faint_with_no_reserve_pokemon_returns_correct_decisions(self): self.state.self.active.hp = 0 self.state.opponent.active.hp = 0 for mon in self.state.self.reserve.values(): mon.hp = 0 expected_options = ( [ constants.DO_NOTHING_MOVE ], [ 'switch yveltal', 'switch slurpuff', 'switch victini', 'switch toxapex', 'switch bronzong' ], ) options = self.state.get_all_options() self.assertEqual(expected_options, options)