Beispiel #1
0
 async def req_loader(self, req: str):
     """
     Parse and translate json send by server. Reload bot team. Called each turn.
     :param req: json sent by server.
     """
     jsonobj = json.loads(req)
     self.turn += 2
     self.bot_team = Team()
     for pkm in jsonobj['side']['pokemon']:
         try:
             new_pkm = Pokemon(
                 pkm['ident'].split(': ')[1],
                 pkm['details'].split(',')[0],
                 pkm['condition'],
                 pkm['active'],
                 pkm['details'].split(',')[1].split('L')[1] if len(pkm['details']) > 1 and 'L' in pkm['details'] else 100
             )
             new_pkm.load_known([pkm['baseAbility']], pkm["item"], pkm['stats'], pkm['moves'])
             self.bot_team.add(new_pkm)
         except IndexError as error:
             print(f'\033[31mIndexError: {error}\n{pkm}\033[0m')
             exit(2)
     if 'forceSwitch' in jsonobj.keys():
         await self.make_switch()
     elif 'active' in jsonobj.keys():
         self.current_pkm = jsonobj['active']
Beispiel #2
0
def effi_pkm(battle, pkm1: Pokemon, pkm2: Pokemon, team1: Team,
             team2: Team) -> int:
    """
    Efficiency of pokemon against other.
    Based on move efficiency functions.
    If efficiency of a pokemon > 150 and is faster, efficiency of the other pokemon is not taken.
    effi_pkm(a, b, team_a) = - effi_pkm(b, a, team_b)
    :param battle: Battle object, current battle.
    :param pkm1: Pokemon that will use move.
    :param pkm2: Pokemon that will receive move.
    :param team1: Team of pkm1.
    :param team2: Team of pkm2.
    :return: Integer, can be negative.
    """
    pkm1_spe = pkm1.compute_stat(Stats.SPE)
    pkm2_spe = pkm2.compute_stat(Stats.SPE)

    effi1 = max(
        [effi_move(battle, move, pkm1, pkm2, team2) for move in pkm1.moves])
    if effi1 >= base_damages(150, pkm1, pkm2) and pkm1_spe > pkm2_spe:
        return effi1
    effi2 = max(
        [effi_move(battle, move, pkm2, pkm1, team1) for move in pkm2.moves])
    if effi2 >= base_damages(150, pkm2, pkm1) and pkm2_spe > pkm1_spe:
        return -effi2
    return effi1 - effi2
Beispiel #3
0
 async def req_loader(self, req, websocket):
     """
     Parse and translate json send by server. Reload bot team. Called each turn.
     :param req: json sent by server.
     :param websocket: Websocket stream.
     """
     jsonobj = json.loads(req)
     self.turn += 2
     objteam = jsonobj['side']['pokemon']
     self.bot_team = Team()
     for pkm in objteam:
         try:
             newpkm = Pokemon(pkm['details'].split(',')[0], pkm['condition'], pkm['active'],
                              pkm['details'].split(',')[1].split('L')[1]
                              if len(pkm['details']) > 1 and 'L' in pkm['details'] else 100)
             newpkm.load_known([pkm['baseAbility']], pkm["item"], pkm['stats'], pkm['moves'])
             self.bot_team.add(newpkm)
         except IndexError as e:
             print("\033[31m" + "IndexError: " + str(e))
             print(pkm + "\033[0m")
             exit(2)
     if "forceSwitch" in jsonobj.keys():
         await self.make_switch(websocket)
     elif "active" in jsonobj.keys():
         self.current_pkm = jsonobj["active"]
Beispiel #4
0
def fill_table_for_pokemon(pokemon, all_pokemon, cup):
    ally_name, ally_fast, ally_charge_1, ally_charge_2 = pokemon
    ally = Pokemon(ally_name, ally_fast, ally_charge_1, ally_charge_2)
    to_write = []
    for enemy_name, enemy_fast, enemy_charge_1, enemy_charge_2 in all_pokemon:
        enemy = Pokemon(enemy_name, enemy_fast, enemy_charge_1, enemy_charge_2)
        results = battle_all_shields(ally, enemy)
        to_write.append([str(ally), str(enemy)] + list(x[0] for x in results))

    command = "INSERT INTO battle_sims(ally, enemy, zeroVzero, zeroVone, zeroVtwo, oneVzero, oneVone, oneVtwo, twoVzero, twoVone, twoVtwo) VALUES (?,?,?,?,?,?,?,?,?,?,?)"
    conn = sqlite3.connect(f"{path}/data/databases/{cup}.db")
    cur = conn.cursor()
    cur.executemany(command, to_write)
    conn.commit()
    conn.close()
Beispiel #5
0
def effi_boost(move: dict, pkm1: Pokemon, pkm2: Pokemon) -> bool:
    """
    Calculate if boost is worth or not. Currently only working on speed.
    :param move: Json object, status move.
    :param pkm1: Pokemon that will use move.
    :param pkm2: Pokemon that will receive move.
    :return: Boolean, True if worth, else False
    """
    pkm1_spe = stat_calculation(pkm1.stats[Stats.SPE], pkm1.level, 252)
    move = next((i for i in pkm1.moves if i['name'] == move['move']))
    value = ((move.get('secondary') if move.get('secondary') else move)
        .get('self', move).get('boosts', {}).get('spe', 0))
    if not value:
        return False
    return (pkm2.compute_stat(Stats.SPE) > pkm1.compute_stat(Stats.SPE)
        and pkm1_spe * (value + pkm1.buff_affect(Stats.SPE)) > pkm2.compute_stat(Stats.SPE))
Beispiel #6
0
def base_damages(power: float, pkm1: Pokemon, pkm2: Pokemon) -> int:
    """
    Used to compare damage done by pk1 to comparative values (100, 150, etc.).
    Because we want exact values, modificators, stab, burn and efficiency are
    not taken into account.
    :param power: value to compare
    :param pkm1: Pokemon that will use move.
    :param pkm2: Pokemon that will receive move.
    :return: Integer, damage of comparative value after calculation [0, +oo[
    """
    categories = Stats.SPA, Stats.SPD
    if pkm1.stats[Stats.ATK] > pkm1.stats[Stats.SPA]:
        categories = Stats.ATK, Stats.DEF
    atk = pkm1.compute_stat(categories[0])
    defe = pkm2.compute_stat(categories[1])
    return floor(((0.4 * pkm1.level + 2) * (atk / defe) * power) / 50 + 2)
Beispiel #7
0
    def update_enemy(self, pkm_name, level, condition):
        """
        On first turn, and each time enemy switch, update enemy team and enemy current pokemon.
        :param pkm_name: Pokemon's name
        :param level: int, Pokemon's level
        :param condition: str current_hp/total_hp. /100 if enemy pkm.
        """
        if "-mega" in pkm_name.lower():
            self.enemy_team.remove(pkm_name.lower().split("-mega")[0])
        if "-*" in pkm_name.lower():
            pkm_name = re.sub(r"(.+)-\*", r"\1", pkm_name)
        elif re.compile(r".+-.*").search(pkm_name.lower()):
            try:
                self.enemy_team.remove(re.sub(r"(.+)-.+", r"\1", pkm_name))
            except NameError:
                pass

        if pkm_name not in self.enemy_team:
            for pkm in self.enemy_team.pokemons:
                pkm.active = False
            pkm = Pokemon(pkm_name, condition, True, level)
            pkm.load_unknown()
            self.enemy_team.add(pkm)
        else:
            for pkm in self.enemy_team.pokemons:
                if pkm.name.lower() == pkm_name.lower():
                    pkm.active = True
                else:
                    pkm.active = False
Beispiel #8
0
    def update_enemy(self, pkm_name: str, condition: str, pkm_variant: str = None, level: str = None):
        """
        On first turn, and each time enemy switch, update enemy team and enemy current pokemon.
        :param pkm_name: Pokemon's name
        :param condition: str current_hp/total_hp. % if enemy pkm.
        :param level: stringified int, Pokemon's level. Can be None if pokemon already exists.
        :param pkm_variant: Pokemon's variant name. Can be None if pokemon already exists.
        """
        for pkm in self.enemy_team.pokemons:
            pkm.active = False

        if pkm := next((pkm for pkm in self.enemy_team.pokemons if pkm.name == pkm_name), None):
            pkm.active = True
            pkm.condition = condition
        else:
            pkm = Pokemon(pkm_name, pkm_variant, condition, True, level)
            pkm.load_unknown()
            self.enemy_team.add(pkm)

    @staticmethod
    def update_status(pokemon, status: str = ''):
        """
        Update status problem.
        :param pokemon: Pokemon.
        :param status: String.
        """
        match status:
            case 'tox':
                pokemon.status = Status.TOX
            case 'brn':
                pokemon.status = Status.BRN
Beispiel #9
0
def battle(ally: Pokemon, enemy: Pokemon, ally_shields: int,
           enemy_shields: int):
    ally.starting_shields = ally_shields
    enemy.starting_shields = enemy_shields

    ally.reset()
    enemy.reset()

    turns = 0

    # Main Battle Loop
    while ally.is_alive() and enemy.is_alive():
        ally.reduce_cooldown()
        enemy.reduce_cooldown()

        turns += 1
        if ally.can_act():
            if not ally.use_charge_move(enemy):
                ally.use_move(ally.fast_move, enemy)

        if enemy.can_act():
            if not enemy.use_charge_move(ally):
                enemy.use_move(enemy.fast_move, ally)

    # There are 2 points for using enemy shields and 3 for using enemy health.
    ally_rating = enemy.starting_shields - enemy.get_shields()
    enemy_rating = ally.starting_shields - ally.get_shields()
    ally_rating += round(
        7 * (enemy.starting_health - enemy.get_health()) /
        enemy.starting_health, 1)
    enemy_rating += round(
        7 * (ally.starting_health - ally.get_health()) / ally.starting_health,
        1)
    if ally.get_health() > 0:
        ally_rating += round(3 * ally.energy / 100, 1)
    if enemy.get_health() > 0:
        enemy_rating += round(3 * enemy.energy / 100, 1)

    total_rating = ally_rating + enemy_rating

    return int(round(1000 * ally_rating / total_rating,
                     0)), int(round(1000 * enemy_rating / total_rating, 0))
Beispiel #10
0
        enemy.starting_health, 1)
    enemy_rating += round(
        7 * (ally.starting_health - ally.get_health()) / ally.starting_health,
        1)
    if ally.get_health() > 0:
        ally_rating += round(3 * ally.energy / 100, 1)
    if enemy.get_health() > 0:
        enemy_rating += round(3 * enemy.energy / 100, 1)

    total_rating = ally_rating + enemy_rating

    return int(round(1000 * ally_rating / total_rating,
                     0)), int(round(1000 * enemy_rating / total_rating, 0))


def battle_all_shields(ally: Pokemon, enemy: Pokemon):
    to_return = []
    for ally_shields in range(3):
        for enemy_shields in range(3):
            to_return.append(battle(ally, enemy, ally_shields, enemy_shields))
    return to_return


if __name__ == '__main__':
    hitmonchan = Pokemon('Hitmonchan', 'Counter', 'Power-Up Punch',
                         'Ice Punch')
    medicham = Pokemon('Medicham', 'Counter', 'Power-Up Punch', 'Psychic')
    results = battle_all_shields(hitmonchan, medicham)
    for result in results:
        print(result)
Beispiel #11
0
def add_pokemon_to_ranking_table(pokemon, cup, mean, sd, i):
    conn = sqlite3.connect(f"{path}/data/databases/{cup}.db")
    cur = conn.cursor()
    command = f"SELECT fast, charge_1, charge_2, absolute_rank FROM rankings WHERE pokemon = ? ORDER BY absolute_rank DESC"
    cur.execute(command, (pokemon, ))
    rows = cur.fetchall()
    p = Pokemon(pokemon, rows[0][0], rows[0][1], rows[0][2])
    best_matchups, worst_matchups, optimal_team = combos(cup, str(p), cur)
    data = {
        'name':
        pokemon,
        'relative_rank':
        i,
        'color':
        calculate_color(mean, sd, rows[0][3]),
        'absolute_rank':
        rows[0][3],
        'level':
        p.level,
        'atk':
        p.ivs['atk'],
        'def':
        p.ivs['def'],
        'sta':
        p.ivs['hp'],
        'optimal_team':
        ', '.join(optimal_team),
        'best_matchups':
        ', '.join(best_matchups),
        'worst_matchups':
        ', '.join(worst_matchups),
        'movesets': [{
            'fast_type': gm.get_move(row[0])['type'],
            'fast': row[0],
            'charge_1_type': gm.get_move(row[1])['type'],
            'charge_1': row[1],
            'charge_2_type': gm.get_move(row[2])['type'],
            'charge_2': row[2],
            'absolute_rank': row[3],
            'string': f"{cup}+{pokemon}+{row[0]}+{row[1]}+{row[2]}"
        } if row[2] else {
            'fast_type': gm.get_move(row[0])['type'],
            'fast': row[0],
            'charge_1_type': gm.get_move(row[1])['type'],
            'charge_1': row[1],
            'charge_2_type': None,
            'charge_2': None,
            'absolute_rank': row[3],
            'string': f"{cup}+{pokemon}+{row[0]}+{row[1]}"
        } for row in rows]
    }
    conn.close()
    conn = sqlite3.connect(f"{path}/web/{cup}.db")
    cur = conn.cursor()
    cur.execute(
        "INSERT INTO rankings VALUES (?,?,?,?,?,?,?,?,?,?,?)",
        (data['name'], data['relative_rank'], data['absolute_rank'],
         data['color'], data['level'], data['atk'], data['def'], data['sta'],
         data['best_matchups'], data['worst_matchups'], data['optimal_team']))
    command = "INSERT INTO all_pokemon VALUES(?,?,?,?,?,?,?,?,?)"
    bindings = [
        (data['name'], moveset['absolute_rank'], moveset['fast'],
         moveset['fast_type'], moveset['charge_1'], moveset['charge_1_type'],
         moveset['charge_2'], moveset['charge_2_type'], moveset['string'])
        for moveset in data['movesets']
    ]
    cur.executemany(command, bindings)
    conn.commit()
    conn.close()