class Hero: username: str health: float damage: float level: int def __init__(self, username: str, level: int, health: float, damage: float): self.username = username self.level = level self.health = health self.damage = damage def battle(self, enemy_hero): if enemy_hero.username == self.username: raise Exception("You cannot fight yourself") if self.health <= 0: raise ValueError("Your health is lower than or equal to 0. You need to rest") if enemy_hero.health <= 0: raise ValueError(f"You cannot fight {enemy_hero.username}. He needs to rest") player_damage = self.damage * self.level enemy_hero_damage = enemy_hero.damage * enemy_hero.level self.health -= enemy_hero_damage enemy_hero.health -= player_damage if self.health <= 0 and enemy_hero.health <= 0: return "Draw" if enemy_hero.health <= 0: self.level += 1 self.health += 5 self.damage += 5 return "You win" enemy_hero.level += 1 enemy_hero.health += 5 enemy_hero.damage += 5 return "You lose" def __str__(self): return f"Hero {self.username}: {self.level} lvl\n" \ f"Health: {self.health}\n" \ f"Damage: {self.damage}\n" import unittest class TestHero(unittest.TestCase): def setUp(self): self.hero = Hero('Hero', 1, 100, 100) self.enemy = Hero('Enemy', 1, 50, 50) def test_init(self): self.assertEqual('Hero', self.hero.username) self.assertEqual(1, self.hero.level) self.assertEqual(100, self.hero.health) self.assertEqual(100, self.hero.damage) def test_hero_is_the_same_as_enemy_raise_exception(self): with self.assertRaises(Exception) as ex: self.hero.battle(self.hero) self.assertEqual("You cannot fight yourself", str(ex.exception)) def test_hero_with_zero_energy(self): self.hero.health = 0 with self.assertRaises(ValueError) as ex: self.hero.battle(self.enemy) self.assertEqual("Your health is lower than or equal to 0. You need to rest", str(ex.exception)) def test_enemy_with_zero_energy(self): self.enemy.health = 0 with self.assertRaises(ValueError) as ex: self.hero.battle(self.enemy) self.assertEqual("You cannot fight Enemy. He needs to rest", str(ex.exception)) def test_battle_returns_draw(self): self.hero.health = 50 result = self.hero.battle(self.enemy) self.assertEqual(0, self.hero.health) self.assertEqual(-50, self.enemy.health) self.assertEqual('Draw', result) def test_battle_enemy_and_win_expect(self): result = self.hero.battle(self.enemy) self.assertEqual(2, self.hero.level) self.assertEqual(55, self.hero.health) self.assertEqual(105, self.hero.damage) self.assertEqual('You win', result) def test_battle_enemy_and_lose_expect_hero_stats_improve(self): self.hero, self.enemy = self.enemy, self.hero result = self.hero.battle(self.enemy) self.assertEqual(2, self.enemy.level) self.assertEqual(55, self.enemy.health) self.assertEqual(105, self.enemy.damage) self.assertEqual("You lose", result) def test_correct_str(self): self.assertEqual( f"Hero Hero: 1 lvl\n" \ f"Health: 100\n" \ f"Damage: 100\n", str(self.hero)) if __name__ == '__main__': unittest.main()