Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
140 lines solution in Creative category for The Warlords by CDG.Axel
class Weapon:
def __init__(self, health, attack, defense=0, vampirism=0, heal_power=0):
self.health, self.attack, self.defense = health, attack, defense
self.vampirism, self.heal_power = vampirism, heal_power
class Sword(Weapon):
def __init__(self):
super().__init__(5, 2)
class Shield(Weapon):
def __init__(self):
super().__init__(20, -1, 2)
class GreatAxe(Weapon):
def __init__(self):
super().__init__(-15, 5, -2, 10)
class Katana(Weapon):
def __init__(self):
super().__init__(-20, 6, -5, 50)
class MagicWand(Weapon):
def __init__(self):
super().__init__(30, 3, 0, 0, 3)
class Warrior:
def __init__(self, health=50, attack=5, defense=0, vampirism=0, penetration=0, heal_power=0, priority=2):
self.max_health = self.health = health
self.attack, self.defense, self.vampirism = attack, defense, vampirism
self.penetration, self.heal_power, self.priority = penetration, heal_power, priority
@property
def is_alive(self):
return self.health > 0
def make_hit(self, target, second=None, behind=None):
dmg = max(0, self.attack - target.defense)
target.health -= dmg
self.health += int(dmg * self.vampirism / 100)
behind.heal(self) if type(behind) is Healer else None
if second:
second.health -= max(0, int(dmg * self.penetration / 100) - second.defense)
return target.is_alive
def heal(self, target):
target.health = min(target.max_health, target.health + self.heal_power * self.is_alive)
def equip_weapon(self, weapon: Weapon):
self.max_health = self.health = self.health + weapon.health
self.attack = max(0, self.attack + weapon.attack) if self.attack else 0
self.defense = max(0, self.defense + weapon.defense) if self.defense else 0
self.vampirism = max(0, self.vampirism + weapon.vampirism) if self.vampirism else 0
self.heal_power = max(0, self.heal_power + weapon.heal_power) if self.heal_power else 0
class Knight(Warrior):
def __init__(self):
super().__init__(50, 7)
class Defender(Warrior):
def __init__(self):
super().__init__(60, 3, 2)
class Vampire(Warrior):
def __init__(self):
super().__init__(40, 4, 0, 50)
class Lancer(Warrior):
def __init__(self):
super().__init__(50, 6, 0, 0, 50, 0, 1)
class Healer(Warrior):
def __init__(self):
super().__init__(60, 0, 0, 0, 0, 2, 0)
class Warlord(Warrior):
def __init__(self):
super().__init__(100, 4, 2, 0, 0, 0, 3)
def fight(atk, defender, atk_b=None, defender_b=None):
while atk.is_alive and defender.is_alive:
defender.make_hit(atk, atk_b, defender_b) if atk.make_hit(defender, defender_b, atk_b) else None
return atk.is_alive
class Army(list):
def add_units(self, unit, count: int):
self.extend([unit() for _ in range(1 - self.is_any_warlord() if unit == Warlord else count)])
def remove_killed(self):
x, _ = [unit for unit in self if unit.is_alive], self.clear()
self.extend(x)
def move_units(self):
if self.is_any_warlord():
self.sort(key=lambda x: x.priority)
for i, unit in enumerate(self):
if type(unit) not in [Healer, Warlord]:
self.insert(0, self.pop(i))
break
def is_any_warlord(self):
return any(type(unit) is Warlord for unit in self)
@property
def units(self):
return self
@property
def second(self) -> Warrior:
return self[1] if len(self) > 1 else None
class Battle:
@staticmethod
def fight(army1: Army, army2: Army):
while army1 and army2:
army1.move_units(), army2.move_units()
fight(army1[0], army2[0], army1.second, army2.second)
army1.remove_killed(), army2.remove_killed()
return bool(army1)
@staticmethod
def straight_fight(army1: Army, army2: Army):
while army1 and army2:
[fight(a1, a2) for a1, a2 in zip(army1, army2)]
army1.remove_killed(), army2.remove_killed()
return bool(army1)
if __name__ == '__main__':
#These "asserts" using only for self-checking and not necessary for auto-testing
ronald = Warlord()
heimdall = Knight()
assert fight(heimdall, ronald) == False
my_army = Army()
my_army.add_units(Warlord, 1)
my_army.add_units(Warrior, 2)
my_army.add_units(Lancer, 2)
my_army.add_units(Healer, 2)
enemy_army = Army()
enemy_army.add_units(Warlord, 3)
enemy_army.add_units(Vampire, 1)
enemy_army.add_units(Healer, 2)
enemy_army.add_units(Knight, 2)
my_army.move_units()
enemy_army.move_units()
assert type(my_army.units[0]) == Lancer
assert type(my_army.units[1]) == Healer
assert type(my_army.units[-1]) == Warlord
assert type(enemy_army.units[0]) == Vampire
assert type(enemy_army.units[-1]) == Warlord
assert type(enemy_army.units[-2]) == Knight
#6, not 8, because only 1 Warlord per army could be
assert len(enemy_army.units) == 6
battle = Battle()
assert battle.fight(my_army, enemy_army) == True
print("Coding complete? Let's try tests!")
Oct. 6, 2021