• Loss of attribute during army battle

Question related to mission Army Battles

 

I don't fully understand why yet, but my code doesn't work properly (meaning there may be some mistakes below). However, there is a loss of my health attribute for the Warrior class when I run my code in Checkio but not in another compiler. I've pasted the entire code below. The Warrior class is at the top, so you can see that I've instantiated HP for health.

Here is the exact error message I receive: AttributeError: type object 'Warrior' has no attribute 'HP' fight, 54 <module>, 131

line 54 is as follows:

B.HP -= A.dmg #A attacks

It is from within the battle.fight method pasted in full below.

Line 131 is as follows:

    assert battle.fight(my_army, enemy_army) == True

is line 131. When I run this same setup in Jupyter Notebooks, it works fine.

class Warrior:
def __init__(self):
    self.HP = 50
    self.dmg = 5
    self.name = "Warrior"

def __repr__(self):
    return self.name

@property
def is_alive(self) -> bool:
    return self.HP > 0


class Knight(Warrior):
    def __init__(self):
        self.HP = 50
        self.dmg = 7
        self.name = "Knight"

def fight(A, B):
        while A.is_alive and B.is_alive:
            B.HP -= A.dmg #A attacks
            if B.is_alive:
                A.HP -= B.dmg #B attacks
        return A.is_alive #Must be moved outside of 'while' loop to work properly.

class Army:
    def __init__(self):
        self.roster = []

@property
def remaining_fighters(self) -> bool:
    return len(self.roster) > 0

def add_units(self, unit, number):
    while number > 0:
        self.roster.append(unit)
        number -= 1

class Battle:

def fight(self, army1, army2):
    A = army1.roster[0] #Initialize fighter for army 1.
    B = army2.roster[0] #Initialize fighter for army 2.
    #Loop for army battle.
    while army1.remaining_fighters and army2.remaining_fighters:
        #Original fight loop
        while A.is_alive and B.is_alive:
            B.HP -= A.dmg #A attacks
            if B.is_alive:
                A.HP -= B.dmg #B attacks
        #Remove dead fighter and assign new one for army 1.
        if not A.is_alive:
            army1.roster.remove(A)
            if army1.remaining_fighters:
                A = army1.roster[0]
                A.HP = 50
        #Remove dead fighter and assign new one for army 2.
        elif not B.is_alive:
            army2.roster.remove(B)
            if army2.remaining_fighters:
                B = army2.roster[0]
                B.HP = 50
    #Victory conditions
    if not army1.roster:
        return False
    elif not army2.roster:
        return True