def test_start_round(self): with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battlemaster = Battlemaster() unit_charlie = self._make_unit(is_player=True, level=13) unit_omega = self._make_unit(is_player=True, level=13) battle.add_combatant(combatant=unit_charlie) battle.add_combatant(combatant=unit_omega) # Make sure battle was added battlemaster.add_battle(battle=battle) # Lizard poisons Spock attacker_weapon = self._make_item(item_type="lizard") target_weapon = self._make_item(item_type="spock") unit_charlie.equip_item(item=attacker_weapon) unit_omega.equip_item(item=target_weapon) dungeon = self._make_dungeon() battle.start_round(battle=battle, irc="quux", ircmsgs=ircmsgs, dungeon=dungeon, ircutils=ircutils) self.assertFalse(unit_omega.has_full_hp()) self.assertTrue(unit_charlie.has_full_hp()) self.assertTrue(len(battle.rounds), 2)
def test_add_battle(self): with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battlemaster = Battlemaster() unit_charlie = self._make_unit(is_player=True, level=13) unit_omega = self._make_unit(is_player=True, level=13) battle.add_combatant(combatant=unit_charlie) battle.add_combatant(combatant=unit_omega) # Make sure battle was added battlemaster.add_battle(battle=battle) attacker_weapon = self._make_item(item_type="lizard") target_weapon = self._make_item(item_type="spock") unit_charlie.equip_item(item=attacker_weapon) unit_omega.equip_item(item=target_weapon) hit_info = unit_charlie.attack(target=unit_omega) battle.add_round(attacker=unit_charlie, target=unit_omega, hit_info=hit_info) self.assertEqual(len(battle.rounds), 1)
def test_can_add_round(self): """ Test that: 1. We have not exceeded the total rounds for this battle 2. All combatants are alive 3. No combatant can attack the same target twice in a row """ with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger, total_rounds=1) battlemaster = Battlemaster() unit_charlie = self._make_unit(is_player=True, level=99) unit_omega = self._make_unit(is_player=True, level=13) battle.add_combatant(combatant=unit_charlie) battle.add_combatant(combatant=unit_omega) # Make sure battle was added battlemaster.add_battle(battle=battle) # Target's Scissors cut Attacker's Paper attacker_weapon = self._make_item(item_type="lizard") target_weapon = self._make_item(item_type="spock") unit_charlie.equip_item(item=attacker_weapon) unit_omega.equip_item(item=target_weapon) """ Sunny day scenario """ can_add_round = battle.can_add_round(attacker=unit_charlie, target=unit_omega) self.assertTrue(can_add_round) """ Test that we cannot exceed total rounds """ dungeon = self._make_dungeon() battle.start_round(battle=battle, ircutils="quux", ircmsgs="quux", irc="quux", dungeon=dungeon) self.assertEqual(len(battle.rounds), 1) # Swap combatant order so it is someone else's turn battle.combatants = list(reversed(battle.combatants)) cannot_exceed_rounds_error = battle.can_add_round(attacker=unit_charlie, target=unit_omega) self.assertEqual(cannot_exceed_rounds_error, "Cannot add round: maximum rounds reached.")
def test_not_your_turn(self): """ Unit should not be able to attack twice in a row """ with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battlemaster = Battlemaster() unit_charlie = self._make_unit(is_player=False, level=99) unit_omega = self._make_unit(is_player=False, level=13) battle.add_combatant(combatant=unit_charlie) battle.add_combatant(combatant=unit_omega) # Make sure battle was added battlemaster.add_battle(battle=battle) # Target's Scissors cut Attacker's Paper attacker_weapon = self._make_item(item_type="lizard") target_weapon = self._make_item(item_type="spock") unit_charlie.equip_item(item=attacker_weapon) unit_omega.equip_item(item=target_weapon) dungeon = self._make_dungeon() battle.start_round(battle=battle, irc="quux", ircmsgs="foo", dungeon=dungeon, ircutils="quux") """ unit_charle's Lizard poisons unit_omega's Spock """ self.assertFalse(unit_omega.has_full_hp()) self.assertTrue(unit_charlie.has_full_hp()) self.assertTrue(len(battle.rounds), 2) """ Try to attack again (should work since this is not pvp) """ can_start_reason = battle.start_round(battle=battle, irc="quux", ircmsgs="foo", dungeon=dungeon, ircutils="quux") self.assertTrue(can_start_reason) self.assertTrue(len(battle.rounds), 3)
def test_cannot_start_battle_with_no_combatants(self): with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battlemaster = Battlemaster() """ Attempting to add a battle with less than two combatants should raise ValueError """ try: battlemaster.add_battle(battle=battle) except ValueError: self.assertEqual(len(battlemaster.battles), 0)
def test_target_retaliation(self): """ Tests the the following use case: 1. Attacker strikes 2. Target is equipped with a counter item type 3. Attacker should miss and then take damage from the target unit's attack """ with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battlemaster = Battlemaster() unit_charlie = self._make_unit(is_player=True, level=13) unit_omega = self._make_unit(is_player=True, level=13) battle.add_combatant(combatant=unit_charlie) battle.add_combatant(combatant=unit_omega) # Make sure battle was added battlemaster.add_battle(battle=battle) # Target's Scissors cut Attacker's Paper attacker_weapon = self._make_item(item_type="paper") target_weapon = self._make_item(item_type="scissors") unit_charlie.equip_item(item=attacker_weapon) unit_omega.equip_item(item=target_weapon) dungeon = self._make_dungeon() battle.start_round(battle=battle, irc="quux", ircmsgs="foo", dungeon=dungeon, ircutils="quux") """ Since Unit Omega had scissors equipped they should have dealt damage to Unit Charlie """ self.assertFalse(unit_charlie.has_full_hp()) self.assertTrue(unit_omega.has_full_hp()) self.assertTrue(len(battle.rounds), 2)
def test_cannot_battle_unit_in_combat(self): """ Units should not be able to start a battle if either of them are currently engaged in a battle. """ unit_alpha = self._make_unit(level=13) unit_bravo = self._make_unit(level=13) unit_delta = self._make_unit(level=13) # Engage first two targets in battle with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger, total_rounds=2) battle.add_combatant(unit_alpha) battle.add_combatant(unit_bravo) self.assertEqual(len(battle.combatants), 2) battlemaster = Battlemaster() battlemaster.add_battle(battle=battle) """ Make sure we can't add a combatant in battle to another battle simultaneously """ with LogCapture(): logger = logging.getLogger() another_battle = Battle(log=logger) another_battle.add_combatant(unit_alpha) another_battle.add_combatant(unit_bravo) another_battle.add_combatant(unit_delta) """ Attempting to do this should not work because two of the combatants are in battle. """ battlemaster.add_battle(battle=another_battle) self.assertEqual(len(battlemaster.battles), 1)
def test_battle_add_challenge(self): """ In order to engage in combat, the unit must consent to a challenge. NPCs should accept automatically; an attack with an NPC target generates a challenge. If NPC: - issue challenge immediately adds challenge if PC: - issue challenge adds to battlemaster.challenges and accepting adds hostile combatant to target A battle ending or a unit dying should clear hostile combatants """ with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battlemaster = Battlemaster() unit_charlie = self._make_unit(is_player=True, level=13) unit_omega = self._make_unit(is_player=True, level=13) """ Could adding a combatant automatically issue a challenge? """ battle.add_combatant(combatant=unit_charlie) battle.add_combatant(combatant=unit_omega) self.assertEqual(len(battle.combatants), 2, "Failed to add combatants") """ The battlemaster issues a challenge on behalf of unit_charlie! """ battlemaster.issue_challenge(attacker=unit_charlie, target=unit_omega) self.assertEqual(len(battlemaster.challenges), 1) """ After the challenge has been issued, verify that the Battlemaster has recorded that """ has_challenged = \ battlemaster.has_accepted_challenge(attacker=unit_charlie, target=unit_omega) self.assertFalse(has_challenged, "Failed to issue challenge") # Attempt to accept challenge battlemaster.accept_challenge_from_target(attacker=unit_charlie, target=unit_omega) accepted_challenge = \ battlemaster.has_accepted_challenge(attacker=unit_charlie, target=unit_omega) self.assertTrue(accepted_challenge, "Failed to accept challenge")
def test_add_battle_with_rounds(self): combatant_1 = self._make_unit(level=13, is_player=False) combatant_2 = self._make_unit(level=13, is_player=False) with LogCapture(): logger = logging.getLogger() battle = Battle(log=logger) battle.add_combatant(combatant_1) battle.add_combatant(combatant_2) self.assertEqual(len(battle.combatants), 2) battlemaster = Battlemaster() battlemaster.add_battle(battle=battle) self.assertEqual(len(battlemaster.battles), 1) actual_1 = battlemaster.get_battle_by_combatant(combatant=combatant_1) self.assertIsNotNone(actual_1) self.assertEqual(battle, actual_1) actual_2 = battlemaster.get_battle_by_combatant(combatant=combatant_2) self.assertIsNotNone(actual_2) self.assertEqual(battle, actual_2) self.assertTrue(combatant_1.is_alive()) self.assertTrue(combatant_2.is_alive()) """ Round 1 """ attacker_weapon = self._make_item(item_type="rock") target_weapon = self._make_item(item_type="scissors") combatant_1.equip_item(item=attacker_weapon) combatant_2.equip_item(item=target_weapon) dungeon = self._make_dungeon() battle.start_round(battle=battle, irc="quux", ircutils="quux", ircmsgs="quux", dungeon=dungeon) self.assertEqual(len(battle.rounds), 1) rounds_won_for_combatant_1 = battle.get_rounds_won( combatant=combatant_1) rounds_won_for_combatant_2 = battle.get_rounds_won( combatant=combatant_2) self.assertEqual(rounds_won_for_combatant_1, 1) self.assertEqual(rounds_won_for_combatant_2, 0) """ Round 2 """ round_2_attacker_weapon = self._make_item(item_type="paper") round_2_target_weapon = self._make_item(item_type="rock") combatant_2.equip_item(item=round_2_attacker_weapon) combatant_1.equip_item(item=round_2_target_weapon) battle.combatants = list(reversed(battle.combatants)) battle.start_round(battle=battle, irc="quux", ircutils="quux", ircmsgs="quux", dungeon=dungeon) self.assertEqual(len(battle.rounds), 2) rounds_won_for_combatant_1 = battle.get_rounds_won( combatant=combatant_1) rounds_won_for_combatant_2 = battle.get_rounds_won( combatant=combatant_2) self.assertEqual(rounds_won_for_combatant_1, 1) self.assertEqual(rounds_won_for_combatant_2, 1) """ Round 3 """ round_3_attacker_weapon = self._make_item(item_type="lizard") round_3_target_weapon = self._make_item(item_type="spock") combatant_1.equip_item(item=round_3_attacker_weapon) combatant_2.equip_item(item=round_3_target_weapon) battle.combatants = list(reversed(battle.combatants)) battle.start_round(battle=battle, irc="quux", ircutils="quux", ircmsgs="quux", dungeon=dungeon) self.assertEqual(len(battle.rounds), 3) rounds_won_for_combatant_1 = battle.get_rounds_won( combatant=combatant_1) rounds_won_for_combatant_2 = battle.get_rounds_won( combatant=combatant_2) self.assertEqual(rounds_won_for_combatant_1, 2) self.assertEqual(rounds_won_for_combatant_2, 1) """ Make sure we can't exceed max rounds """ cannot_add_round_reason = battle.can_add_round(attacker=combatant_1, target=combatant_2) self.assertEqual(cannot_add_round_reason, "Cannot add round: maximum rounds reached.") self.assertEqual(len(battle.rounds), 3)