def test_when_enemy_fists_are_weaker_than_spell_then_return_spell(self): enemy = Enemy(150, 50, 50) spell = Spell(name="Fireball", damage=150, mana_cost=50, cast_range=2) spell.equip_to(enemy) self.assertEqual(enemy.attack(), spell) self.assertEqual(getattr(enemy, 'mana'), 0)
def test_when_hero_has_same_attack_points_as_enemy_armor_points(self): dungeon = Dungeon('level1.txt') hero = Hero(name="Bron", title="Dragonslayer", health=100, mana=100, mana_regeneration_rate=2) dungeon.spawn(hero) hero.equip(Weapon('Axe', 20)) hero.equip(Armor('Shield', 20)) enemy = Enemy(50, 50, 20) enemy.equip(Armor('Vest', 20)) result = dungeon._fight(enemy) self.assertTrue('Hero got tired and let his guard down.' in result)
def move_hero(self, direction): if not isinstance(direction, str): raise ValueError('Wrong input - you must enter string!') if direction not in available_directions: raise ValueError('Incorrect value!') if not self.hero.is_alive(): print('Your hero is dead. He cannot move.') return self.hero.direction = direction oldX = self.hero.coordinate_x oldY = self.hero.coordinate_y newX = self.hero.coordinate_x newY = self.hero.coordinate_y if direction == right: newX += 1 elif direction == left: newX -= 1 elif direction == up: newY -= 1 else: newY += 1 if newX >= len(self.map[0]) - 1 or newX < 0 or newY >= len( self.map) or newY < 0: print('Hero is on the edge of the map - you cannot go outside it!') elif self.map[newY][newX] == '#': print('There is an obstacle - you can not move there!') elif self.map[newY][newX] == 'T': print('You have found a treasure!', end=' ') hero_find_treasure(self.hero) self.move_and_regenerate(oldX, oldY, newX, newY) elif self.map[newY][newX] == '.': self.move_and_regenerate(oldX, oldY, newX, newY) elif self.map[newY][newX] == 'E': choice = self.warn_player_when_walking() if choice == 'n': return else: enemy = Enemy(self.level_enemy_health, self.level_enemy_mana, self.level_enemy_damage) fight = Fight(self.hero, enemy, ['E']) outcome = fight.fight() if outcome is True: self.move_and_regenerate(oldX, oldY, newX, newY) else: return True elif self.map[newY][newX] == 'G': print('Congratulations! You have completed the level!') return True
def test_when_hero_attacks_and_enemy_has_armor_with_lower_armor_points( self): dungeon = Dungeon('level1.txt') hero = Hero(name="Bron", title="Dragonslayer", health=100, mana=100, mana_regeneration_rate=2) hero.equip(Weapon('Axe', 20)) enemy = Enemy(50, 50, 20) enemy.equip(Armor('Vest', 10)) expected_damage_taken = 10 result_damage_taken = dungeon.attack(hero, enemy)[0] self.assertEqual(result_damage_taken, expected_damage_taken)
def test_enemy_init_initializes_object_as_expected(self): health = 100 mana = 50 damage = 20 test_obj = Enemy(health, mana, damage) self.assertEqual(getattr(test_obj, 'health'), health) self.assertEqual(getattr(test_obj, 'mana'), mana) self.assertEqual(getattr(test_obj, 'damage'), damage)
def calculate_enemy_stats(self): counter = self.count_enemies() if counter == 0: counter = 1 enemy_health = 100 // counter if enemy_health == 0: enemy_health = 10 enemy_damage = 30 // counter if enemy_damage == 0: enemy_damage = 5 return Enemy(enemy_health, 100, enemy_damage)
def test_when_hero_has_no_weapon_or_spell(self): dungeon = Dungeon('level1.txt') hero = Hero(name="Bron", title="Dragonslayer", health=100, mana=100, mana_regeneration_rate=2) dungeon.spawn(hero) enemy = Enemy(50, 50, 20) result = dungeon._fight(enemy) self.assertTrue( 'He doesn`t stand a chance against the enemy.' in result)
def hero_attack(self, by=''): if by == weapon: print('Weapons can attack only enemies on your position!') elif by == spell and self.hero.can_cast(): if self.hero.spell is None: print('You do not have a spell to attack by a spell!') list_of_values = self.check_cast_range_in_direction_when_attacking_by_spell( ) if self.hero.direction == up or self.hero.direction == left: list_of_values = list_of_values[::-1] if 'E' in list_of_values: index_of_enemy = list_of_values.index('E') if list_of_values[index_of_enemy - 1] == '#': print( 'Nothing to cast against your spell in that direction.' ) choice = self.warn_player_when_casting_spell() if choice == 'n': print('Your hero stays where he is.') else: enemy = Enemy(self.level_enemy_health, self.level_enemy_mana, self.level_enemy_damage) fight = Fight(self.hero, enemy, list_of_values) outcome = fight.fight() if outcome is True: self.change_map_after_casting_spell_and_battle(True) else: self.change_map_after_casting_spell_and_battle(False) else: print('Nothing in casting range ' + str(self.hero.spell.cast_range)) else: print("You don't have enough mana to cast that spell!")
def move_hero(self, direction): way = {'up': {'x': -1, 'y': 0}, 'down': {'x': 1, 'y': 0}, 'left': {'x': 0, 'y': -1}, 'right': {'x': 0, 'y': 1}} if type(direction) is not str: raise TypeError('Direction must be of "str" type.') elif direction not in way.keys(): raise Exception('Unrecognized direction.') elif not self.hero: print('Start a new game!') return new_pos_x = self.hero_coordinates['x'] + way[direction]['x'] new_pos_y = self.hero_coordinates['y'] + way[direction]['y'] self.hero.regenerate_mana() if self._check_if_invalid_position(new_pos_x, new_pos_y) or \ self._check_if_obstacle(new_pos_x, new_pos_y): print('You cannot go there!') return print('==================================================================') if self._check_if_walkable_path(new_pos_x, new_pos_y): self.__move_hero_to_position(new_pos_x, new_pos_y, '.') print('Successfully moved.') elif self._check_if_treasure(new_pos_x, new_pos_y): self.__move_hero_to_position(new_pos_x, new_pos_y, '.') self.pick_treasure(self.hero) elif self._check_if_spawn_point(new_pos_x, new_pos_y): self.__move_hero_to_position(new_pos_x, new_pos_y, 'S') print('Successfully moved.') elif self._check_if_gateway(new_pos_x, new_pos_y): self.__move_hero_to_position(new_pos_x, new_pos_y, '.') print('CONGRATULATIONS!\nYOU WON!') elif self._check_if_enemy(new_pos_x, new_pos_y): enemy = Enemy(50, 50, 20) fight_result = '' fight_result += '*** A fight is started between: ***\n' fight_result += (f'Our hero - {self.hero.known_as()} (health = {self.hero.get_health()}, ' f'mana = {self.hero.get_mana()}) and\n') fight_result += (f'Enemy (health = {enemy.get_health()}, mana = {enemy.get_mana()}, ' f'damage = {getattr(enemy,"damage")})\n') fight_result += '***********************************\n' fight_result += self._fight(enemy) if self.hero.is_alive(): fight_result += 'Enemy is dead!' self.__move_hero_to_position(new_pos_x, new_pos_y, '.') else: fight_result += 'Hero died!\n' self.map[self.hero_coordinates['x']][self.hero_coordinates['y']] = self.last_step self.hero = None if self.spawn(self.saved_hero): fight_result += 'Hero Respawned.' else: fight_result += 'Hero could not respawn.\n--- GAME OVER ---' print(fight_result) if self.hero: self.print_map()
def hero_attack(self, by): if self.hero is None: print('No hero on the map. Try to spawn a new one.') return if by == 'magic': # Fix casting_range = self.hero.get_spell_cast_range() if casting_range == -1: print('Hero doesn`t know any spells') return elif not self.hero.can_cast(): print('Hero has no mana to cast the spell') return else: enemy_pos = self.check_for_enemy(casting_range) if enemy_pos['x'] != -1 and enemy_pos['y'] != -1: enemy = Enemy(50, 50, 20) path = self.bfs((enemy_pos['x'], enemy_pos['y'])) print('A fight is started between:') print(f'Our hero - {self.hero.known_as()} (health = {self.hero.get_health()}, ' f'mana = {self.hero.get_mana()})\nand') print(f'Enemy(health={enemy.get_health()}, mana={enemy.get_mana()}, ' 'damage={getattr(enemy,"damage")})') for elem in path: self.hero.regenerate_mana() hero_weapon = self.hero.attack(by='magic') if type(hero_weapon) == Spell: hero_weapon_name = getattr(hero_weapon, 'name') hero_weapon_damage = getattr(hero_weapon, 'damage') print(f'Hero casts a {hero_weapon_name}, hits enemy for {hero_weapon_damage}.') enemy.take_damage(hero_weapon_damage) else: print('Hero is out of mana.') if not enemy.is_alive(): print('Enemy is dead.') return else: print('Enemy moved one square.') if self.map[elem[0]][elem[1]] == 'T': self.pick_treasure(enemy) self._fight(enemy) if self.hero.is_alive(): print('Enemy is dead!') else: print('Hero died!') self.map[self.hero_coordinates['x']][self.hero_coordinates['y']] = self.last_step self.hero = None if self.spawn(self.saved_hero): print('Hero Respawned.') else: print('Hero could not respawn.') print('-GAME OVER-') else: print(f'No enemy in casting range: {casting_range}.') else: raise Exception('Unrecognized means of attack.')
def test_enemy_validation_raises_typeerror_if_damage_not_int_or_float(self): damage = 'damage' with self.assertRaisesRegex(TypeError, 'Damage must be of "int" / "float" type.'): Enemy.validate_input_enemy(damage)
def test_when_enemy_fists_are_weaker_than_weapon_then_return_weapon(self): enemy = Enemy(150, 50, 50) weapon = Weapon('Axe', 100) weapon.equip_to(enemy) self.assertEqual(enemy.attack(), weapon)
def test_when_enemy_fists_are_stronger_than_weapons_then_return_fists(self): enemy = Enemy(150, 50, 50) weapon = Weapon('Axe', 10) weapon.equip_to(enemy) self.assertEqual(enemy.attack(), Weapon('Fists', 50))
def test_when_enemy_has_no_weapons_or_spells_then_return_fists(self): test_obj = Enemy(150, 50, 20) self.assertEqual(test_obj.attack(), Weapon('Fists', 20))
def test_enemy_take_mana_returns_false(self): enemy = Enemy(100, 50, 20) self.assertFalse(enemy.take_mana())
def test_enemy_validation_raises_exception_if_damage_is_negative(self): damage = -5 with self.assertRaisesRegex(ValueError, 'Damage should be positive.'): Enemy.validate_input_enemy(damage)