Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for The Weapons by Rcp8jzd
class Warrior:
"""Define a warrior."""
def __init__(self, health=50, attack=5):
self.base_health = health
self.health = health
self.attack = attack
@property
def is_alive(self):
return self.health > 0
def hit(self, other):
other.loss(self.attack)
def damage(self, attack):
return attack
def loss(self, attack):
self.health -= self.damage(attack)
def equip_weapon(self, weapon):
self.base_health = max(self.health + weapon.health, 0)
self.health = self.base_health
self.attack = max(self.attack + weapon.attack, 0)
class Knight(Warrior):
"""Define a knight, it's a warrior with an increased attack of 7."""
def __init__(self):
super().__init__(attack=7)
class Defender(Warrior):
"""Define a defender, it's a warrior with a defense field,
a decreased attack of 3 and an increased health of 60."""
def __init__(self):
super().__init__(health=60, attack=3)
self.defense = 2
def damage(self, attack):
return max(0, attack - self.defense)
def equip_weapon(self, weapon):
super().equip_weapon(weapon)
self.defense = max(self.defense + weapon.defense, 0)
class Vampire(Warrior):
"""Define a vampire, it's a warrior with a vampirism field,
a decreased attack of 4 and a decreased health of 40."""
def __init__(self):
super().__init__(health=40, attack=4)
self.vampirism = 50
def hit(self, other):
super().hit(other)
self.health = min(self.health + other.damage(self.attack)
* self.vampirism // 100, self.base_health)
def equip_weapon(self, weapon):
super().equip_weapon(weapon)
self.vampirism = max(self.vampirism + weapon.vampirism, 0)
class Lancer(Warrior):
"""Define a lancer, it's a warrior with an increased attack of 6 that also
deals half damage to the person behind the enemy"""
def __init__(self):
super().__init__(attack=6)
class Healer(Warrior):
"""Define a healer, it's a warrior with no attack but that can heal its
previous ally each time they attack"""
def __init__(self):
super().__init__(health=60, attack=0)
self.heal_power = 2
def heal(self, unit):
"""Heal an ally of 2 or """
unit.health = min(unit.base_health, unit.health + self.heal_power)
def equip_weapon(self, weapon):
super().equip_weapon(weapon)
self.heal_power = max(self.heal_power + weapon.heal_power, 0)
class Weapon:
"""Define a weapon, that can modify the unit's stats but not under 0"""
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):
"""Define a sword, it's a weapon that gives health +5, attack +2"""
def __init__(self):
super().__init__(health=5, attack=2)
class Shield(Weapon):
"""Define a shield, it's a weapon that gives health +20, attack -1,
defense +2 """
def __init__(self):
super().__init__(health=20, attack=-1, defense=2)
class GreatAxe(Weapon):
"""Define a great axe, it's a weapon that gives health -15,
attack +5, defense -2, vampirism +10%"""
def __init__(self):
super().__init__(health=-15, attack=5, defense=-2, vampirism=10)
class Katana(Weapon):
"""Define a katana, it's a weapon that gives health -20, attack +6,
defense -5, vampirism +50% """
def __init__(self):
super().__init__(health=-20, attack=6, defense=-5, vampirism=50)
class MagicWand(Weapon):
"""Define a magic wand, it's a weapon that gives health +30, attack +3,
heal_power +3 """
def __init__(self):
super().__init__(health=30, attack=3, heal_power=3)
def fight(unit_1, unit_2):
"""Duel fight... Is unit_1 stronger than unit_2?"""
while 1:
unit_1.hit(unit_2)
if unit_2.health <= 0:
return True
unit_2.hit(unit_1)
if unit_1.health <= 0:
return False
class Army:
"""Define an army."""
def __init__(self):
"""An empty army for start."""
self.units = []
def add_units(self, unit_class, count):
"""Add an amount of specific units to the army."""
for _ in range(count):
self.units.append(unit_class())
@property
def first_alive_unit(self):
"""First unit alive of the army."""
for unit in self.units:
if unit.is_alive:
return unit
def next_unit(self, unit):
"""Unit next to an unit, if existing"""
i = self.units.index(unit)
if i + 1 < len(self.units):
return self.units[i + 1]
@property
def is_alive(self):
"""Does the army have a living unit?"""
return self.first_alive_unit is not None
@property
def alive_units(self):
"""All living units"""
return [unit for unit in self.units if unit.is_alive]
class Battle:
@staticmethod
def hit(unit_1, army_1, unit_2, army_2):
unit_3 = army_2.next_unit(unit_2)
unit_4 = army_1.next_unit(unit_1)
unit_1.hit(unit_2)
if isinstance(unit_1, Lancer):
if unit_3:
unit_3.loss(unit_1.attack // 2)
if unit_4 and isinstance(unit_4, Healer):
unit_4.heal(unit_1)
@classmethod
def fight(cls, army_1, army_2):
"""A conventional fight. The first alive warrior of an army attacks
the other army's first alive warrior until one army is destroyed"""
while army_1.is_alive and army_2.is_alive:
unit_1 = army_1.first_alive_unit
unit_2 = army_2.first_alive_unit
while 1:
cls.hit(unit_1, army_1, unit_2, army_2)
if unit_2.health <= 0:
break
cls.hit(unit_2, army_2, unit_1, army_1)
if unit_1.health <= 0:
break
return army_1.is_alive
@staticmethod
def straight_fight(army_1, army_2):
"""A multiple fight. At each round, every warrior faces one opponent
of the enemy's army."""
while army_1.is_alive and army_2.is_alive:
army_1_round = army_1.alive_units
army_2_round = army_2.alive_units
for i in range(min(len(army_1_round),
len(army_2_round))):
unit_1 = army_1_round[i]
unit_2 = army_2_round[i]
fight(unit_1, unit_2)
return army_1.is_alive
if __name__ == '__main__':
# These "asserts" using only for self-checking and not necessary for
# auto-testing
ogre = Warrior()
lancelot = Knight()
richard = Defender()
eric = Vampire()
freelancer = Lancer()
priest = Healer()
sword = Sword()
shield = Shield()
axe = GreatAxe()
katana = Katana()
wand = MagicWand()
super_weapon = Weapon(50, 10, 5, 150, 8)
ogre.equip_weapon(sword)
ogre.equip_weapon(shield)
ogre.equip_weapon(super_weapon)
lancelot.equip_weapon(super_weapon)
richard.equip_weapon(shield)
eric.equip_weapon(super_weapon)
freelancer.equip_weapon(axe)
freelancer.equip_weapon(katana)
priest.equip_weapon(wand)
priest.equip_weapon(shield)
assert ogre.health == 125
assert lancelot.attack == 17
assert richard.defense == 4
assert eric.vampirism == 200
assert freelancer.health == 15
assert priest.heal_power == 5
assert not fight(ogre, eric)
assert not fight(priest, richard)
assert fight(lancelot, freelancer)
my_army = Army()
my_army.add_units(Knight, 1)
my_army.add_units(Lancer, 1)
enemy_army = Army()
enemy_army.add_units(Vampire, 1)
enemy_army.add_units(Healer, 1)
my_army.units[0].equip_weapon(axe)
my_army.units[1].equip_weapon(super_weapon)
enemy_army.units[0].equip_weapon(katana)
enemy_army.units[1].equip_weapon(wand)
battle = Battle()
assert battle.fight(my_army, enemy_army)
print("Coding complete? Let's try tests!")
March 5, 2020
Comments: