def find_best_switch(self): #build tree switchRoot = Tree() # find worst case move used on each possible switched in Pokemon battle_copy = deepcopy(self) battle_copy.opponent.lock_moves() try: pokemon_sets = get_pokemon_sets(battle_copy.opponent.active.name) except KeyError: logger.warning("No set for {}".format(battle_copy.opponent.active.name)) return opponent_possible_moves = sorted(pokemon_sets[MOVES_STRING], key=lambda x: x[1], reverse=True) for reservePkm in self.user.reserve: if reservePkm.hp == 0: continue worstCase = 0 for move in opponent_possible_moves: if move[0].startswith("hiddenpower"): continue selfCopy = deepcopy(self) selfCopy.user.active = reservePkm state = selfCopy.create_state() damageEstimate = _calculate_damage(state.opponent.active,state.self.active,move[0]) if damageEstimate != None: if damageEstimate[0] > worstCase: worstCase = damageEstimate[0] switchNode = Tree() switchNode.data = "switch " + reservePkm.name switchNode.maximinScore = worstCase*-0.667 switchRoot.children.append(switchNode) # traverse Tree with root switchRoot return treeTraversalDFS(switchRoot)
def attack_or_switch(self): if self.user.last_used_move[1].startswith("switch"): return "ATTACK" if self.user.active.hp == 0: return "SWITCH" waitingPkm = False; for pkm in self.user.reserve: if not pkm.fainted: waitingPkm = True break if not waitingPkm: return "ATTACK" battle_copy = deepcopy(self) battle_copy.opponent.lock_moves() try: pokemon_sets = get_pokemon_sets(battle_copy.opponent.active.name) except KeyError: logger.warning("No set for {}".format(battle_copy.opponent.active.name)) return opponent_possible_moves = sorted(pokemon_sets[MOVES_STRING], key=lambda x: x[1], reverse=True) worstCaseDmgTaken = 0 for move in opponent_possible_moves: if move[0].startswith("hiddenpower"): continue selfCopy = deepcopy(self) state = selfCopy.create_state() damageEstimate = _calculate_damage(state.opponent.active,state.self.active,move[0]) if damageEstimate != None: if damageEstimate[0] > worstCaseDmgTaken: worstCaseDmgTaken = damageEstimate[0] bestCaseDmgGiven = 0 for move in self.user.active.moves: if move.name.startswith("hiddenpower"): continue selfCopy = deepcopy(self) state = selfCopy.create_state() attacking_move = deepcopy(all_move_json.get(move.name, None)) attacking_type = attacking_move.get(constants.CATEGORY) if attacking_type == constants.STATUS: score = 40 else: score = _calculate_damage(state.self.active,state.opponent.active,move.name)[0] if score != None: if score > bestCaseDmgGiven: bestCaseDmgGiven = score if bestCaseDmgGiven >= worstCaseDmgTaken: return "ATTACK" else: return "SWITCH"
def prepare_battles(self, guess_mega_evo_opponent=True, join_moves_together=False): """Returns a list of battles based on this one The battles have the opponent's reserve pokemon's unknowns filled in The opponent's active pokemon in each of the battles has a different set""" battle_copy = deepcopy(self) battle_copy.opponent.lock_moves() battle_copy.user.lock_active_pkmn_first_turn_moves() if battle_copy.user.active.can_mega_evo: # mega-evolving here gives the pkmn the random-battle spread (Serious + 85s) # unfortunately the correct spread is not stored anywhere as of this being written # this only happens on the turn the pkmn mega-evolves - the next turn will be fine battle_copy.user.active.forme_change(get_mega_pkmn_name(battle_copy.user.active.name)) if guess_mega_evo_opponent and not battle_copy.opponent.mega_revealed() and self.mega_evolve_possible(): check_in_sets = battle_copy.battle_type == constants.STANDARD_BATTLE battle_copy.opponent.active.try_convert_to_mega(check_in_sets=check_in_sets) # for reserve pokemon only guess their most likely item/ability/spread and guess all moves for pkmn in filter(lambda x: x.is_alive(), battle_copy.opponent.reserve): pkmn.guess_most_likely_attributes() try: pokemon_sets = get_pokemon_sets(battle_copy.opponent.active.name) except KeyError: logger.warning("No sets for {}, trying to find most likely attributes".format(battle_copy.opponent.active.name)) battle_copy.opponent.active.guess_most_likely_attributes() return [battle_copy] possible_spreads = sorted(pokemon_sets[SPREADS_STRING], key=lambda x: x[2], reverse=True) possible_abilities = sorted(pokemon_sets[ABILITY_STRING], key=lambda x: x[1], reverse=True) possible_items = sorted(pokemon_sets[ITEM_STRING], key=lambda x: x[1], reverse=True) possible_moves = sorted(pokemon_sets[MOVES_STRING], key=lambda x: x[1], reverse=True) spreads = battle_copy.opponent.active.get_possible_spreads(possible_spreads) items = battle_copy.opponent.active.get_possible_items(possible_items) abilities = battle_copy.opponent.active.get_possible_abilities(possible_abilities) expected_moves, chance_moves = battle_copy.opponent.active.get_possible_moves(possible_moves, battle_copy.battle_type) if join_moves_together: chance_move_combinations = [chance_moves] else: number_of_unknown_moves = max(4 - len(battle_copy.opponent.active.moves) - len(expected_moves), 0) chance_move_combinations = list(itertools.combinations(chance_moves, number_of_unknown_moves)) combinations = list(itertools.product(spreads, items, abilities, chance_move_combinations)) # create battle clones for each of the combinations battles = list() for c in combinations: new_battle = deepcopy(battle_copy) all_moves = [m.name for m in new_battle.opponent.active.moves] all_moves += expected_moves all_moves += c[3] all_moves = [Move(m) for m in all_moves] if join_moves_together or set_makes_sense(c[0][0], c[0][1], c[1], c[2], all_moves): new_battle.opponent.active.set_spread(c[0][0], c[0][1]) if new_battle.opponent.active.name == 'ditto': new_battle.opponent.active.stats = battle_copy.opponent.active.stats new_battle.opponent.active.item = c[1] new_battle.opponent.active.ability = c[2] for m in expected_moves: new_battle.opponent.active.add_move(m) for m in c[3]: new_battle.opponent.active.add_move(m) logger.debug("Possible set for opponent's {}:\t{} {} {} {} {}".format(battle_copy.opponent.active.name, c[0][0], c[0][1], c[1], c[2], all_moves)) battles.append(new_battle) new_battle.opponent.lock_moves() return battles if battles else [battle_copy]
def set_most_likely_pokemon_from_api(pkmn): """Modifies the pkmn object to set the most likely moves/item/ability""" full_sets, move_sets = get_pokemon_sets_and_movesets(pkmn) if full_sets: logger.debug("Using most likely full set for {}".format(pkmn.name)) for pkmn_set in full_sets: pkmn_copy = deepcopy(pkmn) full_set = pkmn_set[0] split_set = full_set.split("|") if pkmn_copy.ability is None: pkmn_copy.ability = split_set[0] if pkmn_copy.item == constants.UNKNOWN_ITEM: pkmn_copy.item = split_set[1] pkmn_copy.set_spread(split_set[2], split_set[3]) for m in split_set[4:8]: if Move(m) not in pkmn_copy.moves: pkmn_copy.add_move(m) if validate_pokemon_set(pkmn_copy): pkmn.ability = pkmn_copy.ability pkmn.item = pkmn_copy.item pkmn.moves = pkmn_copy.moves pkmn.set_spread(split_set[2], split_set[3]) break else: logger.debug("Set {} is invalid for {}".format( full_set, pkmn_copy.name)) elif move_sets: logger.debug( "No full set found for {}, using just the most likely move set". format(pkmn.name)) move_set = move_sets[0][0] pkmn.set_most_likely_item_unless_revealed() pkmn.set_most_likely_ability_unless_revealed() pkmn.set_most_likely_spread() split_set = move_set.split("|") for m in split_set: if Move(m) not in pkmn.moves: pkmn.add_move(m) else: logger.info("Got nothing from the API, using old code") try: pokemon_sets = get_pokemon_sets(pkmn.name) except KeyError: logger.warning( "No sets for {}, trying to find most likely attributes".format( pkmn.name)) pkmn.guess_most_likely_attributes() return possible_abilities = sorted(pokemon_sets["abilities"], key=lambda x: x[1], reverse=True) possible_items = sorted(pokemon_sets["items"], key=lambda x: x[1], reverse=True) possible_moves = sorted(pokemon_sets["moves"], key=lambda x: x[1], reverse=True) items = pkmn.get_possible_items(possible_items) abilities = pkmn.get_possible_abilities(possible_abilities) expected_moves, chance_moves = pkmn.get_possible_moves(possible_moves) all_moves = expected_moves + chance_moves for m in all_moves: pkmn.add_move(m) pkmn.ability = abilities[0] pkmn.item = items[0] pkmn.set_most_likely_spread() logger.debug("Assumed set for opponent's {}:\t{} {} {} {} {}".format( pkmn.name, pkmn.nature, pkmn.evs, pkmn.ability, pkmn.item, pkmn.moves))
def prepare_battles(self, join_moves_together=False): """Returns a list of battles based on this one The battles have the opponent's reserve pokemon's unknowns filled in The opponent's active pokemon in each of the battles has a different set""" battle_copy = deepcopy(self) if not battle_copy.opponent.mega_revealed(): check_in_sets = battle_copy.battle_type == constants.STANDARD_BATTLE battle_copy.opponent.active.try_convert_to_mega( check_in_sets=check_in_sets) # for reserve pokemon only guess their most likely item/ability/spread and guess all moves for pkmn in filter(lambda x: x.is_alive(), battle_copy.opponent.reserve): pkmn.guess_most_likely_attributes() try: pokemon_sets = get_pokemon_sets(battle_copy.opponent.active.name) except KeyError: logger.warning("No set for {}".format( battle_copy.opponent.active.name)) return [battle_copy] possible_spreads = sorted(pokemon_sets[SPREADS_STRING], key=lambda x: x[2], reverse=True) possible_abilities = sorted(pokemon_sets[ABILITY_STRING], key=lambda x: x[1], reverse=True) possible_items = sorted(pokemon_sets[ITEM_STRING], key=lambda x: x[1], reverse=True) possible_moves = sorted(pokemon_sets[MOVES_STRING], key=lambda x: x[1], reverse=True) spreads = battle_copy.opponent.active.get_possible_spreads( possible_spreads) items = battle_copy.opponent.active.get_possible_items(possible_items) abilities = battle_copy.opponent.active.get_possible_abilities( possible_abilities) expected_moves, chance_moves = battle_copy.opponent.active.get_possible_moves( possible_moves, battle_copy.battle_type) if join_moves_together: chance_move_combinations = [chance_moves] else: number_of_unknown_moves = max( 4 - len(battle_copy.opponent.active.moves) - len(expected_moves), 0) chance_move_combinations = list( itertools.combinations(chance_moves, number_of_unknown_moves)) combinations = list( itertools.product(spreads, items, abilities, chance_move_combinations)) logger.debug("Guessing these moves for the opponent's {}: {}".format( battle_copy.opponent.active.name, expected_moves)) # create battle clones for each of the combinations battles = list() for c in combinations: new_battle = deepcopy(battle_copy) all_moves = [m.name for m in new_battle.opponent.active.moves] all_moves += expected_moves all_moves += c[3] if join_moves_together or set_makes_sense(c[0][0], c[0][1], c[1], c[2], all_moves): new_battle.opponent.active.set_spread(c[0][0], c[0][1]) new_battle.opponent.active.item = c[1] new_battle.opponent.active.ability = c[2] for m in expected_moves: new_battle.opponent.active.add_move(m) for m in c[3]: new_battle.opponent.active.add_move(m) logger.debug("Possible set for opponent's {}: {}".format( battle_copy.opponent.active.name, c)) battles.append(new_battle) return battles if battles else [battle_copy]