Skip to content

Duplicate pokemon are not supported on same team #770

Description

@ReynXBC

I am having a strange error where battle.availablemoves is an empty list, despite in the same battle object, i can see the active pokemon and its moves in that list. This is active for an entire battle.

Here is the Player class I am using and observing this error.

class SmartPlayer(Player):
    prevDamagePercent = 100
    currentdamagePercent = 100
    usedMovePreviously = False
    currentOpponent = None
    previousOpponent = None

    def choose_move(self, battle):
        self.currentOpponent = battle.opponent_active_pokemon
        if self.currentOpponent != self.previousOpponent:
            self.currentDamagePercent = 100
            self.previousDamagePercent = 100
            # print(f"New opponent is {self.currentOpponent}")
        else:
            self.currentDamagePercent = battle.opponent_active_pokemon.current_hp
        #    if self.usedMovePreviously:
                # print(f'Actual damage % done was {(self.prevDamagePercent - self.currentDamagePercent)}, previous health % was {self.prevDamagePercent}, current health percentage is {self.currentDamagePercent}%')
        self.prevDamagePercent = self.currentDamagePercent
        self.usedMovePreviously = False
        self.previousOpponent = self.currentOpponent
       
        best_switch = self.choose_best_switch(battle, -1000)
        self.create_order(best_switch)

        # If Pokemon is out of moves, switch to best option
        if not battle.available_moves:
            matchup_score = self.get_matchup_score(battle.active_pokemon, battle.opponent_active_pokemon, battle)
            best_switch = self.choose_best_switch(battle, matchup_score)
            if best_switch is None:
                return self.choose_default_move()  
            return self.create_order(best_switch)
       
        # Use info such as type matchup and relative speed to determine who to switch to
        matchup_score = self.get_matchup_score(battle.active_pokemon, battle.opponent_active_pokemon, battle)
        # If negative situation exceeds threshold, switch Pokemon
        if matchup_score >= 1:
            best_switch = self.choose_best_switch(battle, matchup_score)
            if best_switch is not None:
                return self.create_order(best_switch)
       

        # finds the best move among available ones
        self.usedMovePreviously = True
        best_move = max(battle.available_moves, key=lambda move: BattleUtilities.calculate_damage(move, battle.active_pokemon, battle.opponent_active_pokemon, True, True))
        #print(f'Best move was {best_move}, Calculated damage value was {BattleUtilities.calculate_damage(best_move, battle.active_pokemon, battle.opponent_active_pokemon, True, True)}')
        return self.create_order(best_move)

    def choose_best_switch(self, battle, preswitch_score):
        if not battle.available_switches:
            return None
        # Go through each Pokemon that can be switched to, and choose one with the best type matchup
        # (smaller multipliers are better)
        best_score = float('inf')
        best_switch = battle.available_switches[0]
        for switch in battle.available_switches:
            score = self.get_matchup_score(switch, battle.opponent_active_pokemon, battle)
            if score < best_score:
                best_score = score
                best_switch = switch
        if best_score < preswitch_score:
            return best_switch
        else:
            return None
   
    # Gets a number that determines how well the Pokemon matches up with opponent. Lower scores are better
    def get_matchup_score(self, my_pokemon, opponent_pokemon, battle):
        if my_pokemon is None or opponent_pokemon is None:
            return 0
        score = 0
        defensive_multiplier = BattleUtilities.get_defensive_type_multiplier(my_pokemon, opponent_pokemon)
        # A multiplier greater than 1 means we are at a type disadvantage. If there is a better type match, switch
        if defensive_multiplier == 4:
            score += 1
        elif defensive_multiplier == 2:
            score += 0.5
        elif defensive_multiplier == 0.5:
            score -= 0.5
        elif defensive_multiplier == 0.25:
            score -= 1
        if BattleUtilities.opponent_can_outspeed(my_pokemon, opponent_pokemon):
            score += 0.5
        if my_pokemon.current_hp / my_pokemon.max_hp < 0.25:
            score += 0.25
        effectiveness = 0
        for move in battle.available_moves:
            if BattleUtilities.calculate_damage(move, my_pokemon, opponent_pokemon, True, True) > 0:
                calceffectiveness = opponent_pokemon.damage_multiplier(move.type)
                if calceffectiveness > effectiveness:
                    effectiveness = calceffectiveness
       
        score -= (effectiveness - 1)  # Effectiveness of 1 means no change, so subtract 0
                   
        return score

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions