Light Mode
Dark Mode
Non-deterministic Behavior in Army Battle

In the following scenario my code sometimes returns True and sometimes False. Can somebody see, why?

battle = Battle()
army_1, army_2 = Army(), Army()
army_1.add_units(Warrior, 20)
army_2.add_units(Warrior, 21)
print(battle.fight(army_1, army_2))

Here is my code:

class Warrior:
    _n = count()

    def __init__(self):
        self.h = 50
        self.a = 5
        self.is_alive = True
        self._id = next(Warrior._n)

    def lh(self, o):
        self.h = self.h - o
        self.is_alive = self.h > 0
        print(f"{self} took {o} damage, remaining health: {self.h}")

    def reset(self):
        self.h = 50
        self.is_alive = True

    def __repr__(self):
        return f"{self.__class__.__name__}:{self._id}"

class Knight(Warrior):
    def __init__(self):
        super().__init__()
        self.a = 7

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

    def add_units(self, warrior, amound):
        for i in range(amound): self.warriors.append(warrior())

class Battle():
    def fight(self, my_army, enemy):
        mi, ei = 0, 0
        m, e = [copy.deepcopy(w) for w in my_army.warriors], [copy.deepcopy(w) for w in enemy.warriors]
        f = False

        while mi < len(m) and ei < len(e):
            print(f"{m[mi]} fight against {e[ei]}")
            f = fight(m[mi], e[ei])
            mi, ei = (mi, ei + 1) if f else (mi + 1, ei)

        return mi < len(m)

def fight(a, b):
    m = min(b.h // a.a, a.h // b.a)
    if m * b.a == a.h: m -= 1
    a.lh((m) * b.a)
    b.lh((m+1) * a.a)
    if b.is_alive: a.lh(b.a)
    return a.is_alive
  • code_review
Created: April 23, 2025, 9:13 a.m.
Updated: April 25, 2025, 4:55 p.m.
0
19
User avatar
heinrich.rhing