예제 #1
0
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
예제 #2
0
    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)
예제 #3
0
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)
예제 #4
0
 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"]
예제 #5
0
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)
예제 #6
0
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)
예제 #7
0
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)
예제 #8
0
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)
예제 #9
0
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)
예제 #10
0
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()
예제 #11
0
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