def infos_for_pokemon(pkm_name): """ Filtrate, regroup and translate data from json files. :param pkm_name: Pokemon's name :return: Dict. {types, possibleAbilities, baseStats} """ #pkm_name = pkm_name.lower().replace('-', '').replace(' ', '').replace('%', '').replace('\'', '').replace('.', '') pkm_name = formatting.get_formatted_name(pkm_name) res = { "types": [], "possibleAbilities": [], "baseStats": {} } with open('data/pokedex.json') as data_file: json_dict = json.load(data_file) # load json file # if pokemon in file, use correct stats if (pkm_name in json_dict.keys() ): pokemon = json_dict[pkm_name] res["types"] = pokemon["types"] res["possibleAbilities"] = [ formatting.get_formatted_name(ability) for ability in list(pokemon["abilities"].values()) ] res["baseStats"] = pokemon["baseStats"] else: # if unrecognised, assume Normal with with Illuminate (does nothing) and 70 BST in each stat res["types"] = ["Normal"] res["possibleAbilities"] = [ formatting.get_formatted_name("Illuminate") ] res["baseStats"] = {"hp":70, "atk":70, "def":70, "spa":70, "spd":70, "spe":70} return res
def update_switch(self, side, pokemon_name, position): # get list of bot or foe's pokemon if (side == "bot"): pokemons = self.my_team elif (side == "foe"): pokemons = self.foe_team # make previous active pokemon (if exists) inactive if (self.at_team_preview == False): old_mon = next((mon for mon in pokemons if mon.active == position)) old_mon.switch_out() # make new pokemon active #print("Side: " + side) #print("Foe team: ") #[print(pokemon.id) for pokemon in self.foe_team] #print("Pokemon name: " + pokemon_name) #formatted_name = formatting.get_formatted_name(pokemon_name) #print("Formatted name: " + formatted_name) #print(pokemon_name) #print([mon.id for mon in pokemons]) new_mon = next( mon for mon in pokemons if formatting.get_formatted_name(mon.id.split("-")[0]) == formatting.get_formatted_name(pokemon_name.split("-")[0])) new_mon.switch_in(position)
async def choose_switch(ws, battle, switches): #switches_id = [] switches_names = [] # for each pokemon on team for i, pokemon in enumerate(battle.my_team): # skip if the pokemon is already out, or if fainted if (pokemon.active > 0 or pokemon.fainted): continue # otherwise append to list name = formatting.get_formatted_name(pokemon.id) #switches_id.append(i+1) switches_names.append(name) # figure out number of switches, and randomly pick appropriate number if (switches[0] == switches[1] and len(switches_names) > 1): # 2 switches required switch1, switch2 = random.sample(switches_names, 2) switch_str = "switch " + switch1 + ", switch " + switch2 elif (switches[0] == switches[1] ): # 2 switches required but only 1 mon left switch_str = "switch " + switches_names[0] + ", pass" else: # 1 switch required switch_str = "switch " + random.choice(switches_names) # send switch decision command_str = battle.battletag + "|/choose " + switch_str await senders.send_forced_switch_decision(ws, command_str, battle, format_output)
def load_stats(self): """ Load every information of pokemon from datafiles and store them """ infos = infos_for_pokemon(formatting.get_formatted_name(self.id)) self.types = infos["types"] self.original_types = infos["types"] self.abilities = infos["possibleAbilities"] self.base_stats = infos["baseStats"]
def calculate_score_ratio_switches(battle): scores = [] pokemons = battle.my_team # for each pokemon on team for pokemon in pokemons: # skip if the pokemon is already out, or if fainted if (pokemon.active > 0 or pokemon.fainted): continue # otherwise calculate score ratio and append to list with name name = formatting.get_formatted_name(pokemon.id) ratio = calculate_score_ratio_single(battle, pokemon) scores.append({'name':name, 'ratio':ratio}) # sort if required from highest to lowest ratio if (len(scores) > 0): scores = sorted(scores, key = lambda i: i['ratio'], reverse=True) return(scores)
def get_items_from_line(line): items_data = line.split("\n")[2:] likely_items = [] for item in items_data: for i in range(len(item)): if (item[i].isdigit()): probability = item[i:].split(".")[0] if (int(probability) >= ai_settings.beta): item_name = formatting.get_formatted_name(item[:i]) if (item_name != "nothing"): likely_items.append(item_name) break return (likely_items)
def get_abilities_from_line(line): abilities_data = line.split("\n")[2:] likely_abilities = [] for ability in abilities_data: for i in range(len(ability)): if (ability[i].isdigit()): probability = ability[i:].split(".")[0] if (int(probability) >= ai_settings.gamma): ability_name = formatting.get_formatted_name(ability[:i]) if (ability_name != "nothing"): likely_abilities.append(ability_name) break return (likely_abilities)
def get_moves_from_line(line): moves_data = line.split("\n") moves_data = moves_data[2:len(moves_data) - 2] likely_moves = [] for move in moves_data: for i in range(len(move)): if (move[i].isdigit()): probability = move[i:].split(".")[0] if (int(probability) >= ai_settings.alpha): move_name = formatting.get_formatted_name(move[:i]) if (move_name != "nothing"): likely_moves.append(move_name) break return (likely_moves)
async def send_forced_switch_decision(ws, command_str, battle, format_output=False): command_str += "|" + str(battle.rqid) await ws.send(command_str) if not format_output: print("\nSending forced switch: " + command_str) return # format output to print nicely command_str = command_str.split("|/choose")[-1] switches = [] for i, decision in enumerate(command_str.split(",")): if (decision.split()[0] != "pass"): pokemon_name = [ mon.id for mon in battle.my_team if formatting.get_formatted_name(mon.id) == decision.split()[-1] ] switches.append(pokemon_name[0]) out_string = "\nSwitching to " + " and ".join(switches) + "." print(out_string)
def update_likely_sets(battle, pokemon): #site = "https://www.smogon.com/stats/2019-03/moveset/gen7doublesou-1500.txt" site = "https://www.smogon.com/stats/2020-02/moveset/gen8doublesou-1500.txt" request = requests.get(site) text = request.text pokedex = '\n'.join(text.split('\n')[1:]) pokedex = pokedex.split( "+----------------------------------------+ \n +----------------------------------------+" ) for foe_pokemon in pokemon: print("Getting likely moveset for " + foe_pokemon.id) for pokemon in pokedex: if (formatting.get_formatted_name( foe_pokemon.id) == formatting.get_formatted_name( pokemon.split("|")[1])): condensed_pokemon = pokemon.replace(" ", "").replace("|", "") pokemon_info = condensed_pokemon.split( "+----------------------------------------+") for line in pokemon_info: if ("Moves" in line): moves = get_moves_from_line(line) foe_pokemon.moves = moves elif ("Spreads" in line): highest_evs, nature_buffs = get_spread_from_line(line) foe_pokemon.evs = highest_evs foe_pokemon.nature_buffs = nature_buffs foe_pokemon.calc_stats() elif ("Items" in line): items = get_items_from_line(line) foe_pokemon.item = items elif ("Abilities" in line): abilities = get_abilities_from_line(line) foe_pokemon.abilities = abilities continue # once found pokemon then move onto next one # default moves/stats if don't find in usage if (foe_pokemon.moves == []): foe_pokemon.moves = ["tackle"] foe_pokemon.evs = { "hp": 252, "atk": 252, "def": 252, "spa": 252, "spd": 252, "spe": 252 } foe_pokemon.nature_buffs = { "hp": 1.0, "atk": 1.0, "def": 1.0, "spa": 1.0, "spd": 1.0, "spe": 1.0 } foe_pokemon.calc_stats()
def minor_actions(battle: Battle, split_line, side_dict): status_list = ["brn", "frz", "par", "psn", "tox", "slp"] pos_dict = {"a": 1, "b": 2} # if move fails, e.g. Protect if split_line[0] == "-fail": pass # pokemon takes damage (not just from attacks but also recoil, etc), update HP for foe only elif split_line[0] == "-damage" or split_line[0] == "-heal": side = side_dict[split_line[1][0:2]] # currently only updates foes' health if (side == "foe"): position = pos_dict[split_line[1][2]] pokemon = battle.get_pokemon(side, position) condition = split_line[2].strip("\n") if (condition[-3:] == "fnt"): # fainted pokemon.health_percentage = 0 pokemon.fainted = True pokemon.status = "fnt" else: # set status, should get with -status anyways apart from natural cure! if (condition[-3:] in status_list): pokemon.status = condition[-3:] condition = condition[:-4] else: pokemon.status = None pokemon.health_percentage = int(split_line[2].split("/")[0]) # if from item then note that down if (len(split_line) > 3 and "[from] item:" in split_line[3]): position = pos_dict[split_line[1][2]] pokemon = battle.get_pokemon(side, position) pokemon.item = [ formatting.get_formatted_name(split_line[3].split(':')[-1]) ] # Pokemon heals HP (does same as damage so deal with above) elif split_line[0] == "-heal": pass # given Status, only do for foes elif split_line[0] == "-status": position = pos_dict[split_line[1][2]] side = side_dict[split_line[1][0:2]] status = split_line[2].strip("\n") if (side == "foe"): pokemon = battle.get_pokemon(side, position) pokemon.status = status # cure Status, only do for foes elif split_line[0] == "-curestatus": side = side_dict[split_line[1][0:2]] if (side == "foe"): pokemons = battle.foe_team pokemon_name = split_line[1].split(":")[1].strip() pokemon = next(mon for mon in pokemons if formatting.get_formatted_name(mon.id) == formatting.get_formatted_name(pokemon_name)) pokemon.status = None # cure Status of team, Heal Bell uses above and doesn't actually have this tag elif split_line[0] == "-cureteam": pass # Stat receiving stage boost elif split_line[0] == "-boost": side = side_dict[split_line[1][0:2]] position = pos_dict[split_line[1][2]] stat = split_line[2] amount = int(split_line[3]) battle.add_buff(side, position, stat, amount) # Stat receiving unboost (same as boost with -ve boost) elif split_line[0] == "-unboost": side = side_dict[split_line[1][0:2]] position = pos_dict[split_line[1][2]] stat = split_line[2] amount = -int(split_line[3]) # unboost so negative battle.add_buff(side, position, stat, amount) # Stat stage being set (i.e. Belly Drum) elif split_line[0] == "-setboost": side = side_dict[split_line[1][0:2]] position = pos_dict[split_line[1][2]] stat = split_line[2] amount = int(split_line[3]) # set boost to +6 by adding boost of 12 (meaning -6 and above goes to 6) if (amount == 6): battle.add_buff(side, position, stat, 12) else: print( "Oh no! I don't know what this move is but here is the info:", split_line) # clear all boosts, i.e. Haze elif split_line[0] == "-clearallboost": # reset boosts for all active pokemon pokemons = battle.active_pokemon("both") [pokemon.clear_boosts() for pokemon in pokemons] # Weather, ignore on upkeep messages elif split_line[ 0] == "-weather": #and len(split_line) == 2: #and len(split_line) >= 3 and split_line[2].strip("\n") != "[upkeep]": weather = formatting.format_move(split_line[1]) if (split_line[1].strip("\n") == "none"): battle.weather = None battle.weather_turns_left = 0 elif (weather != battle.weather): battle.weather = formatting.format_move(split_line[1]) battle.weather_turns_left = 5 # Terrain, Trick Room start elif split_line[0] == "-fieldstart": move = formatting.format_move(split_line[1]) if (move == "trickroom"): battle.trick_room = 5 elif ("terrain" in move): battle.terrain = move battle.terrain_turns_left = 5 # Terrain, Trick Room end elif split_line[0] == "-fieldend": move = formatting.format_move(split_line[1]) if (move == "trickroom"): battle.trick_room = 0 elif ("terrain" in move): battle.terrain = None battle.terrain_turns_left = 0 # Screens, entry hazards, Tailwind start elif split_line[0] == "-sidestart": side = side_dict[split_line[1][0:2]] move = formatting.format_move(split_line[2]) if (move == "tailwind"): # Tailwind battle.tailwind[side] = 4 elif (move in battle.entry_hazards[side].keys()): # entry hazards battle.entry_hazards[side][move] += 1 ''' if "Reflect" in split_line[2] or "Light Screen" in split_line[2]: battle.screens[split_line[2].split(":")[1].lower().replace(" ", "")] = True print("** " + battle.screens) ''' # Screens, entry hazards, Tailwind end elif split_line[0] == "-sideend": side = side_dict[split_line[1][0:2]] move = formatting.format_move(split_line[2]) if (move == "tailwind"): # Tailwind battle.tailwind[side] = 0 elif (move in battle.entry_hazards[side].keys()): # entry hazards battle.entry_hazards[side][move] = 0 ''' if "Reflect" in split_line[2] or "Light Screen" in split_line[2]: battle.screens[split_line[2].split(":")[1].lower().replace(" ", "")] = False print("** " + battle.screens) ''' # move crits elif split_line[0] == "-crit": pass # move misses elif split_line[0] == "-miss": pass # move super effective elif split_line[0] == "-supereffective": pass # move resisted elif split_line[0] == "-resisted": pass # move hit immunity elif split_line[0] == "-immune": pass # not seen this happen? elif split_line[0] == "-item": pass ''' if battle.player_id in split_line[1]: battle.bot_team.active().item = split_line[2].lower().replace(" ", "") else: battle.enemy_team.active().item = split_line[2].lower().replace(" ", "") ''' # when lose item, e.g. eat berry or hit by Knock Off elif split_line[0] == "-enditem": position = pos_dict[split_line[1][2]] if (split_line[1][0:2] == battle.my_side): pokemon = battle.get_pokemon("bot", position) else: pokemon = battle.get_pokemon("foe", position) pokemon.has_item = False pokemon.item = [ formatting.get_formatted_name(split_line[2].split(':')[-1]) ] # Ability activation, e.g. Intimidate, Mold Breaker, Clear Body elif split_line[0] == "-ability": position = pos_dict[split_line[1][2]] side = side_dict[split_line[1][0:2]] if (side == "foe"): pokemon = battle.get_pokemon(side, position) pokemon.abilities = [ formatting.get_formatted_name(split_line[2].split(':')[-1]) ] # Ability end, e.g. Neutralizing Gas on leaving field? elif split_line[0] == "-endability": pass # Transform duh elif split_line[0] == "-transform": pass # Mega Evolution, currently deal with under "-detailschange" elif split_line[0] == "-mega": pass # includes Protect, Follow Me, Helping Hand elif split_line[0] == "-singleturn": side = side_dict[split_line[1][0:2]] position = pos_dict[split_line[1][2]] move = formatting.format_move(split_line[2]) if (move == "protect"): pokemon = battle.get_pokemon(side, position) pokemon.can_protect = False # includes making Substitute, Protect, Heal Bell, Skill Swap (if between opponent and us get info about both abilities, if between foes get nothing) elif split_line[0] == "-activate": pass # includes type change from moves like Soak/Burn Up/Conversion; and start of Dynamax elif split_line[0] == "-start": side = side_dict[split_line[1][0:2]] position = pos_dict[split_line[1][2]] pokemon = battle.get_pokemon(side, position) if (split_line[2] == "typeadd"): type = split_line[3].strip("\n") pokemon.types.append(type) elif (split_line[2] == "typechange"): if ("[from]" not in split_line[3]): types = split_line[3].split("/") types = [ type.strip("\n") for type in types if type.strip("\n") != "???" ] pokemon.types = types else: # deal with Reflect Type differently copy_side = side_dict[split_line[4][5:7]] copy_position = pos_dict[split_line[4][7]] copy_pokemon = battle.get_pokemon(copy_side, copy_position) if ( len(copy_pokemon.types) > 0 ): # if target is only ??? then move fails, so don't change type pokemon.types = copy_pokemon.types # Dynamax elif (split_line[2] == "Dynamax"): battle.can_dmax[side] = False pokemon.dynamax = 3 # includes Substitute breaking, Dynamax ending elif split_line[0] == "-end": pass # using the move Transform elif split_line[0] == "-transform": pass elif split_line[0] == "-hitcount": pass # Forewarn and Anticipation maybe? elif split_line[0] == "-hint": pass elif split_line[0] == "-center": pass elif split_line[0] == "-message": pass else: pass