Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
Second solution in Creative category for The Warlords by _Chico_
class Warrior:
max_health = 50
def __init__(self):
self.health = self.max_health
self.attack = 5
@property
def is_alive(self):
return self.health > 0
def hit(self, unit2):
unit2._recieve_damage(self.attack)
def _recieve_damage(self, attack):
defense = getattr(self, 'defense', 0)
attack -= defense
self.health -= attack if attack >= 0 else 0
if self.health < 0:
self.health = 0
def equip_weapon(self, weapon_name):
for attribute in [attr for attr in dir(weapon_name) if not callable(attr) and not attr.startswith('_')]:
if hasattr(self, attribute):
setattr(self, attribute, getattr(self, attribute) + getattr(weapon_name, attribute))
if getattr(self, attribute) < 0:
setattr(self, attribute, 0)
if hasattr(self, 'max_' + attribute):
setattr(self, 'max_' + attribute, getattr(self, 'max_' + attribute) + getattr(weapon_name, attribute))
if getattr(self, 'max_' + attribute) < 0:
setattr(self, 'max_' + attribute, 0)
def __repr__(self):
return f'{self.__class__.__name__}: {self.health} HP' if self.is_alive else f'Dead {self.__class__.__name__}'
class Knight(Warrior):
def __init__(self):
super().__init__()
self.attack = 7
class Defender(Warrior):
max_health = 60
def __init__(self):
super().__init__()
self.defense = 2
self.attack = 3
class Vampire(Warrior):
max_health = 40
def __init__(self):
super().__init__()
self.vampirism = 50
self.attack = 4
def hit(self, unit2):
h1 = unit2.health
unit2._recieve_damage(self.attack)
self.health += int((h1 - unit2.health) * self.vampirism / 100)
class Lancer(Warrior):
def __init__(self):
super().__init__()
self.attack = 6
self.mass_attack = 2
self._reduction_factor = 0.5
def hit(self, enemy):
if hasattr(enemy, '__iter__'):
attack = self.attack
for unit in enemy[:self.mass_attack]:
unit._recieve_damage(attack)
attack *= self._reduction_factor
else:
enemy._recieve_damage(self.attack)
class Healer(Warrior):
max_health = 60
def __init__(self):
super().__init__()
self.attack = 0
self.heal_power = 2
def heal(self, target):
target.health += self.heal_power
if target.health > target.max_health:
target.health = target.max_health
class Warlord(Warrior):
max_health = 100
def __init__(self):
super().__init__()
self.attack = 4
self.defense = 2
def fight(unit_1, unit_2):
units = [unit_1, unit_2]
turn = 0
while all(map(lambda u: u.is_alive, units)):
units[turn].hit(units[not turn])
turn = not turn
return unit_1.is_alive
class Army:
def __init__(self):
self.units = []
self._first_in_place = False
self._has_lancer = False
self._has_healer = False
self._maxpos = 0
def add_units(self, unit_class, amount):
for _ in range(amount):
if unit_class is Warlord:
if [True for unit in self.units if isinstance(unit, Warlord)]: break
self.move_units = self._move_units
self.units.append(unit_class())
def get_warriors(self):
return [unit for unit in self.units if unit.is_alive]
def _sorting_rules(self, unit):
if not unit.is_alive:
return self._maxpos + 100
if isinstance(unit, Lancer):
if self._first_in_place:
return 2 if self._has_healer else 0
else:
self._first_in_place = True
return 0
if isinstance(unit, Healer):
return 1
if isinstance(unit, Warlord):
return self._maxpos + 1
if not self._has_lancer and not self._first_in_place:
self._first_in_place = True
return 0
else:
return self._maxpos
def _move_units(self):
self._first_in_place = False
self._has_lancer = any([u for u in self.units if u.is_alive and isinstance(u, Lancer)])
self._has_healer = any([u for u in self.units if u.is_alive and isinstance(u, Healer)])
self._maxpos = len(self.units)
self.units = sorted(self.units, key=self._sorting_rules)
class Battle:
def fight(self, army1, army2):
while True:
if hasattr(army1, 'move_units'):
army1.move_units()
if hasattr(army2, 'move_units'):
army2.move_units()
units = [army1.get_warriors(), army2.get_warriors()]
if all(units):
turn = 0
while units[0][0].is_alive and units[1][0].is_alive:
if hasattr(units[turn][0], 'mass_attack'):
units[turn][0].hit(units[not turn])
else:
units[turn][0].hit(units[not turn][0])
try:
if hasattr(units[turn][1], 'heal'):
units[turn][1].heal(units[turn][0])
except IndexError:
pass
turn = int(not turn)
else:
return units[0] != []
def straight_fight(self, army1, army2):
while True:
units = [army1.get_warriors(), army2.get_warriors()]
if all(units):
for unit1, unit2 in zip(*units):
fight(unit1, unit2)
else:
return units[0] != []
class Weapon:
def __init__(self, health=0, attack=0, defense=0, vampirism=0, heal_power=0):
if health: self.health = health
if attack: self.attack = attack
if defense: self.defense = defense
if vampirism: self.vampirism = vampirism
if heal_power: self.heal_power = 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)
May 17, 2021