NicK
NicK

Reputation: 31

Program does not recognize value as a valid variable value?

The program I am trying to create involves writing a method called monster_fight(monster1,monster2) to have the two monsters "Fight". However I am having one issue retrieving the damage value stored in each of the monster object dictionaries named 'self.attacks'.

I am trying to retrieve a value from dictionary 'monster1.attacks' to reduce the hp of the monster2 object. However with the current code I have in place, the program does not recognize the value of the keys when I call the dictionary. Can anybody show what I am doing wrong?

Thanks!

class Monster():
    def __init__(self, name, max_hp = 20, hp=20):
        self.name = name
        self.type = type
        self.current_hp = max_hp
        self.attacks = {'wait': 0}
        self.possible_attacks = {'sneak_attack': 1,
                                'slash': 2,
                                'ice_storm': 3,
                                'fire_storm': 3,
                                'whirlwind': 3,
                                'earthquake': 2,
                                'double_hit': 4,
                                'wait': 0}
        self.exp = 0 


    def add_attack(self, attack_name):
        if attack_name in self.possible_attacks:
            self.attacks[attack_name] = self.possible_attacks.get(attack_name)
            return True
        else:
            return False
        if attack_name in self.attacks:
            return False

    def remove_attack(self, attack_name):
        if attack_name in self.attacks:
            self.attacks.pop(attack_name)
            if len(self.attacks) == 0:
                self.attacks['wait'] = 0
            return True
        else:
            return False

    def win_fight(self):
        self.exp += 5
        self.current_hp = self.max_hp

    def lose_fight(self):
        self.exp += 1
        self.current_hp = self.max_hp

def monster_fight(monster1,monster2):
    round1 = 0
    moves1 = []
    moves2 = []
    list1 = []
    list2 = []
    for i in monster1.attacks:
        values = ''
        values = monster1.attacks.get(i)
        list1.append(values)
    for i in range(0,len(monster2.attacks)):
        values = monster2.attacks.get(i)
        list2.append(values)


    while monster1.current_hp > 0 or monster2.current_hp > 0:
        round1 += 1
        monster1_attack = int(monster1.attacks[list1[(round1-1)%len(list1)]])
        monster2.current_hp -= monster1_attack
        moves1.append(list1[(round1-1)%len(list1)])

        monster2_attack= monster2.attacks[list2[(round1-1)%len(list2)]]
        monster1.current_hp -= monster2_attack
        moves2.append(list2[(round1-1)%len(list2)])

    if monster1.current_hp <= 0:
        monster1.lose_fight()
        monster2.win_fight()
        return round1, monster2.name, moves2
    elif monster1.current_hp <= 0:
        monster2.lose_fight()
        monster1.win_fight()
        return round1,monster1.name, moves1
    else:
        return -1,"None","None"



a = Monster("a", 9)
b = Monster("b", 9)
a.add_attack("ice_storm")
b.add_attack("ice_storm")
b.remove_attack("wait")
a.remove_attack("wait")
round1, winner, moves = monster_fight(a, b)
print(round1)
print(winner.name)
print(moves)
monster1_attack = int(monster1.attacks[list1[(round1-1)%len(list1)]])
KeyError: 3

Upvotes: 0

Views: 174

Answers (1)

larsks
larsks

Reputation: 312630

Well, let's see. You're calling:

monster1_attack = int(monster1.attacks[list1[(round1-1)%len(list1)]])

monster1 is a Monster object, created from:

a = Monster("a", 9)
a.add_attack("ice_storm")
a.remove_attack("wait")

So monster1.attacks looks like:

{
  'ice_storm': 3,
}

You're trying to access that dictionary using key dervied from list1[(round1-1)%len(list1)].

list1 is set here:

for i in monster1.attacks:
   values = ''
   values = monster1.attacks.get(i)
   list1.append(values)

After the above code runs, list1 is a list that looks like:

[3]

(Because you ask for monster1.attacks.get(i), which will return the value associated with key i.)

So when you ask for list1[(round1-1)%len(list1)], you get the value 3, which means you're asking for monster1.attacks[3].

There is no key named 3 in monster1.attacks. As we saw earlier, the only key is ice_storm which has the value 3. It looks like you're trying to figure out the damage that monster1's attack will do. That is actually what you have in list1, so in theory you could just write:

monster1_attack = list1[(round1-1)%len(list1)]
monster2.current_hp -= monster1_attack

I think your logic here may be a bit convoluted. You should probably think carefully about exactly what you're trying to accomplish and try to simplify your code with that goal in mind. Using the Python debugger to see the value of your variables prior to the error -- or using print statements to accomplish the same thing -- can help diagnose this sort of problem.

Upvotes: 4

Related Questions