Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for The Warlords by imloafer
# Taken from mission The Weapons
from collections import deque
class Warrior:
def __init__(self, attack=5, health=50, defense=0, vampirism=0, deal_damage=0, heal_power=0):
self.attack = attack
self.health = health
self.defense = defense
self.vampirism = vampirism
self.deal_damage = deal_damage
self.heal_power = heal_power
@property
def is_alive(self):
return self.health > 0
def equip_weapon(self, weapon_name):
self.attack = 0 if self.attack == 0 else max(0, self.attack + weapon_name.attack)
self.health = 0 if self.health == 0 else max(self.health + weapon_name.health, 0)
self.defense = 0 if self.defense == 0 else max(0, self.defense + weapon_name.defense)
self.vampirism = 0 if self.vampirism == 0 else max(0, self.vampirism + weapon_name.vampirism)
self.heal_power = 0 if self.heal_power == 0 else max(0, self.heal_power + weapon_name.heal_power)
class Knight(Warrior):
def __init__(self):
super().__init__(attack=7)
class Defender(Warrior):
def __init__(self):
super().__init__(attack=3, health=60, defense=2)
class Vampire(Warrior):
def __init__(self):
super().__init__(attack=4, health=40, vampirism=50)
class Lancer(Warrior):
def __init__(self):
super().__init__(attack=6, deal_damage=50)
class Healer(Warrior):
def __init__(self):
super().__init__(attack=0, health=60, heal_power=2)
def heal(self, other):
other.health = min(other.health + self.heal_power, type(other)().health)
class Warlord(Warrior):
def __init__(self):
super().__init__(health=100, attack=4, defense=2)
def fight(unit_1, unit_2, unit_1_bkup=None, unit_2_bkup=None):
round = 0
while unit_1.is_alive and unit_2.is_alive:
if round % 2 == 0:
unit_2.health -= max(unit_1.attack - unit_2.defense, 0)
unit_1.health += max((unit_1.attack - unit_2.defense) * unit_1.vampirism//100, 0)
if unit_2_bkup is not None:
unit_2_bkup.health -= max((unit_1.attack - unit_2.defense) * unit_1.deal_damage // 100, 0)
if isinstance(unit_1_bkup, Healer):
unit_1_bkup.heal(unit_1)
else:
unit_1.health -= max(unit_2.attack - unit_1.defense, 0)
unit_2.health += max((unit_2.attack - unit_1.defense) * unit_2.vampirism//100, 0)
if unit_1_bkup is not None:
unit_1_bkup.health -= max((unit_2.attack - unit_1.defense) * unit_2.deal_damage // 100, 0)
if isinstance(unit_2_bkup, Healer):
unit_2_bkup.heal(unit_2)
round += 1
return unit_1.is_alive
class Army:
def __init__(self):
self.units = deque()
def add_units(self, unit, amount):
self.units += [unit() for _ in range(amount)]
@property
def has_warlord(self):
return [x for x in self.units if type(x) == Warlord] != []
def move_units(self):
warlord = [x for x in self.units if type(x) == Warlord][0]
lancers = [x for x in self.units if type(x) == Lancer]
healers = [x for x in self.units if type(x) == Healer]
others = [x for x in self.units if type(x) != Lancer and type(x) != Healer and type(x) != Warlord]
if lancers:
self.units = deque([lancers.pop()] + healers + lancers + others + [warlord])
else:
self.units = deque(([others.pop(0)] if others else []) + healers + others + [warlord])
class Battle:
def fight(self, army_1, army_2):
if army_1.has_warlord:
army_1.move_units()
if army_2.has_warlord:
army_2.move_units()
unit_1 = army_1.units.popleft()
unit_2 = army_2.units.popleft()
try:
unit_1_bkup = army_1.units[0]
except IndexError:
unit_1_bkup = None
try:
unit_2_bkup = army_2.units[0]
except IndexError:
unit_2_bkup = None
res = fight(unit_1, unit_2, unit_1_bkup, unit_2_bkup)
while True:
if res:
if army_2.has_warlord:
army_2.move_units()
try:
unit_2 = army_2.units.popleft()
try:
unit_2_bkup = army_2.units[0]
except IndexError:
unit_2_bkup = None
except IndexError:
break
else:
if army_1.has_warlord:
army_1.move_units()
try:
unit_1 = army_1.units.popleft()
try:
unit_1_bkup = army_1.units[0]
except IndexError:
unit_1_bkup = None
except IndexError:
break
res = fight(unit_1, unit_2, unit_1_bkup, unit_2_bkup)
return res
def straight_fight(self, army_1, army_2):
army_1_alive = [x for x in army_1.units if x.is_alive]
army_2_alive = [x for x in army_2.units if x.is_alive]
while army_1_alive and army_2_alive:
for unit_1, unit_2 in zip(army_1_alive, army_2_alive):
fight(unit_1, unit_2)
army_1_alive = [x for x in army_1.units if x.is_alive]
army_2_alive = [x for x in army_2.units if x.is_alive]
return army_1_alive != []
class Weapon:
def __init__(self, health=0, attack=0, defense=0, vampirism=0, heal_power=0):
self.health = health
self.attack = attack
self.defense = defense
self.vampirism = vampirism
self.heal_power = heal_power
class Sword(Weapon):
def __init__(self):
super().__init__(health=5, attack=2)
class Shield(Weapon):
def __init__(self):
super().__init__(health=20, attack=-1, defense=2)
class GreatAxe(Weapon):
def __init__(self):
super().__init__(health=-15, attack=5, defense=-2, vampirism=10)
class Katana(Weapon):
def __init__(self):
super().__init__(health=-20, attack=6, defense=-5, vampirism=50)
class MagicWand (Weapon):
def __init__(self):
super().__init__(health=30, attack=3, heal_power=3)
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)
print(my_army.has_warlord)
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)
print(len(enemy_army.units))
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
print(type(enemy_army.units[0]))
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
army_1 = Army()
army_2 = Army()
army_1.add_units(Warrior, 2)
army_1.add_units(Lancer, 2)
army_1.add_units(Defender, 1)
army_1.add_units(Warlord, 3)
army_2.add_units(Warlord, 2)
army_2.add_units(Vampire, 1)
army_2.add_units(Healer, 5)
army_2.add_units(Knight, 2)
army_1.move_units()
army_2.move_units()
battle = Battle()
assert battle.fight(army_1, army_2) == False
assert battle.fight(my_army, enemy_army) == True
print("Coding complete? Let's try tests!")
Nov. 18, 2022