Babeeshka Babeeshka - 9 days ago 6
Python Question

Python Class Pokemon Battle

Hey stackoverflow users,

I am trying to write a Python class for a pokemon battle. I followed the posts here, but I am trying to integrate the different pokemon typing. For instance, fire, grass, and water and allow them to function as they do in the game. For example, fire is super effective against grass. I am not sure if I should add in another function for type or define the typing within the constructor and write a series of nesting statements that determine effectiveness or ineffectiveness.

class Pokemon(object):
def __init__(self, name, HP, Damage, type):
self.name = name #Sets the name of the Pokemon
self.HP = HP #The Hit Points or health of this pokemon
self.Damage = Damage #The amount of Damage this pokemon does every attack
self.type = type #Determines the type of the pokmeon to factor in effectiveness

def Battle(self, Opponent):
if self.type == 'grass':
self.Damage = self.Damage * 1.35

if(self.HP > 0): #While your pokemon is alive it will coninute the Battle
print("%s did %d Damage to %s"%(self.name, self.Damage, Opponent.name)) #Text-based combat descriptors
print("%s has %d HP left"%(Opponent.name,Opponent.HP)) #Text-based descriptor for the opponent's health

Opponent.HP -= self.Damage #The damage you inflict upon the opponent is subtracted here
return Opponent.Battle(self) #Now the Opponent pokemon attacks
else:
print("%s wins! (%d HP left)" %(Opponent.name, Opponent.HP)) #declares the winner of the Battle
return Opponent, self #return a tuple (Winner, Loser)

Squirtle = Pokemon('Squirtle', 100, 5, 'water')
Bulbasaur = Pokemon('Bulbasaur', 100, 10, 'grass')
Winner, Loser = Bulbasaur.Battle(Squirtle)

Answer

your problem seems like it could be elegantly solved by Python's dict data type [1] in a nested manner [2]:

attacking = {'fire': {'fire': 0.5, 'grass': 2.0, 'water': 0.5}, 'grass': {'fire': 0.5, 'grass': 0.5, 'water': 2.0}, 'water': {'fire': 2.0, 'grass': 0.5, 'water': 0.5}}

creates a nested dictionary for the weaknesses when the first type attacks. You can then access the multiplier for a fire type attacking a grass type like this:

attacking['fire']['grass'] # yields 2.0

As a side note: you are overwriting the damage of the Pokemon with this instruction: self.Damage = self.Damage * 1.35. This works as long as you don't have e.g. Squirtle battle first a Bulbasaur, then a ground-type Pokemon, against which Squirtle has the effectiveness 1. As soon as you'd start the battle against the Charmander, the damage of the Squirtle will be 5*2.0*1.0 = 10.0, which is not equal to the damage it should deal (5.0). If you created a new variable (turnDamage = self.Damage * attack[self.type][Opponent.type], this would not be a problem.

Yet another edit: this actually works for me:

class Pokemon(object):
    attackingDict = {'fire': {'fire': 0.5, 'grass': 2.0, 'water': 0.5}, 'grass': {'fire': 0.5, 'grass': 0.5, 'water': 2.0}, 'water': {'fire': 2.0, 'grass': 0.5, 'water': 0.5}}
    def __init__(self, name, HP, Damage, type):
        self.name = name     #Sets the name of the Pokemon
        self.HP = HP         #The Hit Points or health of this pokemon
        self.Damage = Damage #The amount of Damage this pokemon does every     attack
        self.type = type #Determines the type of the pokmeon to factor in effectiveness

    def Battle(self, Opponent):
        attackDamage = self.Damage * self.attackingDict[self.type][Opponent.type]

        if(self.HP > 0): #While your pokemon is alive it will coninute the Battle
            print("%s did %d Damage to %s"%(self.name, attackDamage, Opponent.name)) #Text-based combat descriptors
            print("%s has %d HP left"%(Opponent.name,Opponent.HP)) #Text-based descriptor for the opponent's health

            Opponent.HP -= attackDamage #The damage you inflict upon the opponent is subtracted here
            return Opponent.Battle(self)  #Now the Opponent pokemon attacks
        else:
            print("%s wins! (%d HP left)" %(Opponent.name, Opponent.HP)) #declares the winner of the Battle
            return Opponent, self  #return a tuple (Winner, Loser)


Squirtle = Pokemon('Squirtle', 100, 5, 'water')
Bulbasaur = Pokemon('Bulbasaur', 100, 10, 'grass')
Winner, Loser = Bulbasaur.Battle(Squirtle)

The multipliers are intrinsic to the class (i.e. every pokemon obeys the same rules), so the field attackingDict belongs in the class.