# Taken from mission The Lancers # Taken from mission The Vampires # Taken from mission The Defenders # Taken from mission Army Battles # Taken from mission The Warriors class Warrior: def __init__(self): self.health = 50 self.attack = 5 self.is_alive = True self.defense = 0 self.vampirism = 0 self.healing = 0 def hit(self, other_unit) -> bool: hit_points = self.attack - other_unit.defense hit_points = hit_points if hit_points > 0 else 0 other_unit.health -= hit_points other_unit.is_alive = other_unit.health > 0 self.health += (hit_points * self.vampirism) return other_unit.is_alive class Knight(Warrior): def __init__(self): super().__init__() self.attack = 7 class Defender(Warrior): def __init__(self): super().__init__() self.health = 60 self.attack = 3 self.defense = 2 class Vampire(Warrior): def __init__(self): super().__init__() self.health = 40 self.attack = 4 self.vampirism = 0.5 class Rookie(Warrior): def __init__(self, *args, **kwargs): super().__init__() self.health = 50 self.attack = 1 class Lancer(Warrior): def __init__(self): super().__init__() self.attack = 6 class Healer(Warrior): def __init__(self): super().__init__() self.health = 60 self.attack = 0 self.healing = 2 def heal(self, unit: Warrior): unit.health += self.healing def fight(unit_1, unit_2): while unit_1.is_alive and unit_2.is_alive: if not unit_1.hit(unit_2): return True if not unit_2.hit(unit_1): return False class Army: def __init__(self): self.units = [] def add_units(self, unit_type, quantity): for i in range(quantity): self.units.append(unit_type()) class Battle: @staticmethod def fight(army_1: Army, army_2: Army) -> bool: while len(army_1.units) > 0 and len(army_2.units) > 0: current_unit_1 = army_1.units[0] current_unit_2 = army_2.units[0] while current_unit_1.is_alive and current_unit_2.is_alive: current_unit_1_attack = current_unit_1.hit(current_unit_2) if len(army_1.units) > 1 and isinstance(army_1.units[1], Healer): current_unit_1.health += army_1.units[1].healing if isinstance(current_unit_1, Lancer) and len(army_2.units) > 1: army_2.units[1].health -= current_unit_1.attack * 0.5 if not current_unit_1_attack: army_2.units.pop(0) break current_unit_2_attack = current_unit_2.hit(current_unit_1) if len(army_2.units) > 1 and isinstance(army_2.units[1], Healer): current_unit_2.health += army_2.units[1].healing if isinstance(current_unit_2, Lancer) and len(army_1.units) > 1: army_1.units[1].health -= current_unit_2.attack * 0.5 if not current_unit_2_attack: army_1.units.pop(0) break return len(army_1.units) > 0 if __name__ == '__main__': # These "asserts" using only for self-checking and not necessary for auto-testing # fight tests chuck = Warrior() bruce = Warrior() carl = Knight() dave = Warrior() mark = Warrior() bob = Defender() mike = Knight() rog = Warrior() lancelot = Defender() eric = Vampire() adam = Vampire() richard = Defender() ogre = Warrior() freelancer = Lancer() vampire = Vampire() priest = Healer() assert fight(chuck, bruce) == True assert fight(dave, carl) == False assert chuck.is_alive == True assert bruce.is_alive == False assert carl.is_alive == True assert dave.is_alive == False assert fight(carl, mark) == False assert carl.is_alive == False assert fight(bob, mike) == False assert fight(lancelot, rog) == True assert fight(eric, richard) == False assert fight(ogre, adam) == True assert fight(freelancer, vampire) == True assert freelancer.is_alive == True assert freelancer.health == 14 priest.heal(freelancer) assert freelancer.health == 16 # battle tests my_army = Army() my_army.add_units(Defender, 2) my_army.add_units(Healer, 1) my_army.add_units(Vampire, 2) my_army.add_units(Lancer, 2) my_army.add_units(Healer, 1) my_army.add_units(Warrior, 1) enemy_army = Army() enemy_army.add_units(Warrior, 2) enemy_army.add_units(Lancer, 4) enemy_army.add_units(Healer, 1) enemy_army.add_units(Defender, 2) enemy_army.add_units(Vampire, 3) enemy_army.add_units(Healer, 1) army_3 = Army() army_3.add_units(Warrior, 1) army_3.add_units(Lancer, 1) army_3.add_units(Healer, 1) army_3.add_units(Defender, 2) army_4 = Army() army_4.add_units(Vampire, 3) army_4.add_units(Warrior, 1) army_4.add_units(Healer, 1) army_4.add_units(Lancer, 2) battle = Battle() assert battle.fight(my_army, enemy_army) == False assert battle.fight(army_3, army_4) == True print("Coding complete? Let's try tests!")