def create_moves_complex() -> List[Move]: """Create a complex move for testing.""" pawn1 = Pawn(color=PlayerColor.RED, index=1, name="V", position=Position().move_to_safe(3)) position1 = Position().move_to_square(10) pawn2 = Pawn(color=PlayerColor.YELLOW, index=3, name="W", position=Position().move_to_square(10)) position2 = Position().move_to_square(11) pawn3 = Pawn(color=PlayerColor.BLUE, index=2, name="X", position=Position().move_to_square(32)) pawn4 = Pawn(color=PlayerColor.RED, index=3, name="Z", position=Position().move_to_square(17)) position4 = Position().move_to_square(27) move1 = Move( id="a9fff13fbe5e46feaeda87382bf4c3b8", card=Card("card1", CardType.CARD_APOLOGIES), actions=[Action(ActionType.MOVE_TO_POSITION, pawn1, position1), Action(ActionType.MOVE_TO_POSITION, pawn2, position2)], side_effects=[Action(ActionType.MOVE_TO_START, pawn3)], ) move2 = Move( id="d05f9b511b6e439aa18c8b70cbbcc5d3", card=Card("card2", CardType.CARD_10), actions=[Action(ActionType.MOVE_TO_POSITION, pawn4, position4)], side_effects=[], ) return [move1, move2]
def test_play_next_adult_draw_again(self): engine = TestEngine._create_engine(GameMode.ADULT) player = engine._game.players[PlayerColor.RED] pawn = player.pawns[0] view = Mock() movecard1 = player.hand[0] movecard2 = player.hand[1] replacementcard1 = Card(998, CardType.CARD_APOLOGIES) replacementcard2 = Card(999, CardType.CARD_APOLOGIES) move1 = Move(movecard1, [Action(ActionType.MOVE_TO_START, pawn)]) move2 = Move(movecard2, [Action(ActionType.MOVE_TO_POSITION, pawn)]) legal_moves1 = [move1] legal_moves2 = [move2] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( side_effect=[legal_moves1, legal_moves2]) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock( side_effect=[replacementcard1, replacementcard2]) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock( side_effect=[move1, move2]) engine._rules.execute_move = MagicMock() engine._rules.draw_again = MagicMock(side_effect=[True, False]) engine.play_next() engine._game.create_player_view.assert_has_calls( [call(PlayerColor.RED), call(PlayerColor.RED)]) engine._rules.construct_legal_moves.assert_has_calls( [call(view, card=None), call(view, card=None)]) engine.characters[0].choose_move.assert_has_calls([ call(engine.mode, view, legal_moves1, Rules.evaluate_move), call(engine.mode, view, legal_moves2, Rules.evaluate_move) ]) engine._rules.execute_move.assert_has_calls([ call(engine._game, player, move1), call(engine._game, player, move2) ]) engine._game.deck.discard.assert_has_calls( [call(movecard1), call(movecard2)]) engine._rules.draw_again.assert_has_calls( [call(movecard1), call(movecard2)]) assert movecard1 not in player.hand assert movecard2 not in player.hand assert replacementcard1 in player.hand assert replacementcard2 in player.hand
def test_play_next_adult_forfeit(self): engine = TestEngine._create_engine(GameMode.ADULT) player = engine._game.players[PlayerColor.RED] view = Mock() movecard = player.hand[0] replacementcard = Card(999, CardType.CARD_APOLOGIES) move = Move(movecard, []) legal_moves = [move] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock(return_value=replacementcard) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock(return_value=move) engine.play_next() engine._game.create_player_view.assert_called_once_with( PlayerColor.RED) engine._rules.construct_legal_moves.assert_called_once_with(view, card=None) engine.characters[0].choose_move.assert_called_once_with( engine.mode, view, legal_moves, Rules.evaluate_move) engine._game.track.assert_called_once_with( "Turn is forfeit; discarded card %s" % movecard.cardtype.value, player, movecard) engine._game.deck.discard.assert_called_once_with(movecard) assert movecard not in player.hand assert replacementcard in player.hand
def test_play_next_standard_legal(self): engine = TestEngine._create_engine() card = Card(0, CardType.CARD_12) player = engine._game.players[PlayerColor.RED] pawn = player.pawns[0] view = Mock() move = Move(card, [Action(ActionType.MOVE_TO_START, pawn)]) legal_moves = [move] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock(return_value=card) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock(return_value=move) engine._rules.execute_move = MagicMock() engine._rules.draw_again = MagicMock(return_value=False) engine.play_next() engine._game.create_player_view.assert_called_once_with( PlayerColor.RED) engine._rules.construct_legal_moves.assert_called_once_with(view, card=card) engine.characters[0].choose_move.assert_called_once_with( engine.mode, view, legal_moves, Rules.evaluate_move) engine._rules.execute_move.assert_called_once_with( engine._game, player, move) engine._game.deck.discard.assert_called_once_with(card) engine._rules.draw_again.assert_called_once_with(card)
def test_play_next_standard_forfeit(self): engine = TestEngine._create_engine() card = Card(0, CardType.CARD_1) player = engine._game.players[PlayerColor.RED] view = Mock() move = Move(card, []) legal_moves = [move] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock(return_value=card) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock(return_value=move) engine.play_next() engine._game.create_player_view.assert_called_once_with( PlayerColor.RED) engine._rules.construct_legal_moves.assert_called_once_with(view, card=card) engine.characters[0].choose_move.assert_called_once_with( engine.mode, view, legal_moves, Rules.evaluate_move) engine._game.track.assert_called_once_with( "Turn is forfeit; discarded card 1", player, card) engine._game.deck.discard.assert_called_once_with(card)
def create_view() -> PlayerView: """Create a realistic-looking player view for testing.""" player = Player(PlayerColor.RED) player.turns = 16 player.hand = [Card("card1", CardType.CARD_APOLOGIES), Card("card2", CardType.CARD_1)] player.pawns[0].position.move_to_square(32) player.pawns[1].position.move_to_safe(3) player.pawns[2].position.move_to_square(45) opponent = Player(PlayerColor.GREEN) opponent.turns = 15 opponent.hand = [Card("card3", CardType.CARD_5), Card("card4", CardType.CARD_11)] opponent.pawns[1].position.move_to_home() opponent.pawns[2].position.move_to_safe(4) opponent.pawns[3].position.move_to_square(19) opponents = {opponent.color: opponent} return PlayerView(player, opponents)
def test_play_next_standard_draw_again(self): engine = TestEngine._create_engine() card1 = Card(0, CardType.CARD_12) card2 = Card(1, CardType.CARD_10) player = engine._game.players[PlayerColor.RED] pawn = player.pawns[0] view = Mock() move1 = Move(card1, [Action(ActionType.MOVE_TO_START, pawn)]) move2 = Move(card2, [Action(ActionType.MOVE_TO_POSITION, pawn)]) legal_moves1 = [move1] legal_moves2 = [move2] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( side_effect=[legal_moves1, legal_moves2]) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock(side_effect=[card1, card2]) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock( side_effect=[move1, move2]) engine._rules.execute_move = MagicMock() engine._rules.draw_again = MagicMock(side_effect=[True, False]) engine.play_next() engine._game.create_player_view.assert_has_calls( [call(PlayerColor.RED), call(PlayerColor.RED)]) engine._rules.construct_legal_moves.assert_has_calls( [call(view, card=card1), call(view, card=card2)]) engine.characters[0].choose_move.assert_has_calls([ call(engine.mode, view, legal_moves1, Rules.evaluate_move), call(engine.mode, view, legal_moves2, Rules.evaluate_move) ]) engine._rules.execute_move.assert_has_calls([ call(engine._game, player, move1), call(engine._game, player, move2) ]) engine._game.deck.discard.assert_has_calls([call(card1), call(card2)]) engine._rules.draw_again.assert_has_calls([call(card1), call(card2)])
def create_moves_simple() -> List[Move]: """Create a simple move for testing.""" pawn = Pawn(color=PlayerColor.RED, index=1, name="V", position=Position().move_to_safe(3)) position = Position().move_to_square(10) move = Move( id="a9fff13fbe5e46feaeda87382bf4c3b8", card=Card("card1", CardType.CARD_APOLOGIES), actions=[Action(ActionType.MOVE_TO_POSITION, pawn, position)], side_effects=[], ) return [move]
def test_construct_legal_moves_standard_nocard(self): engine = TestEngine._create_engine(mode=GameMode.STANDARD) view = Mock() drawcard = Mock() movecard = Card(0, CardType.CARD_1) move = Move(movecard, []) legal_moves = [move] engine._game.deck.draw = MagicMock(return_value=drawcard) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) assert engine.construct_legal_moves(view) == (drawcard, legal_moves) engine._rules.construct_legal_moves.assert_called_once_with( view, card=drawcard)
def test_construct_legal_moves_adult_card(self): engine = TestEngine._create_engine(mode=GameMode.ADULT) view = Mock() providedcard = Mock() drawcard = Mock() movecard = Card(0, CardType.CARD_1) move = Move(movecard, []) legal_moves = [move] engine._game.deck.draw = MagicMock(return_value=drawcard) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) assert engine.construct_legal_moves( view, card=providedcard) == (providedcard, legal_moves) engine._rules.construct_legal_moves.assert_called_once_with( view, card=providedcard) engine._game.deck.draw.assert_not_called()
def test_play_next_adult_draw_again_complete(self): with patch("apologies.game.Game.completed", new_callable=PropertyMock) as completed: completed.side_effect = [ False, True ] # not complete when we start execution, but complete after the 1st move engine = TestEngine._create_engine(GameMode.ADULT) player = engine._game.players[PlayerColor.RED] pawn = player.pawns[0] view = Mock() movecard = player.hand[0] replacementcard = Card(999, CardType.CARD_APOLOGIES) move = Move(movecard, [Action(ActionType.MOVE_TO_START, pawn)]) legal_moves = [move] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock(return_value=replacementcard) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock(return_value=move) engine._rules.execute_move = MagicMock() engine._rules.draw_again = MagicMock( return_value=True ) # we won't check this because the complete flag is set engine.play_next() engine._game.create_player_view.assert_called_once_with( PlayerColor.RED) engine._rules.construct_legal_moves.assert_called_once_with( view, card=None) engine.characters[0].choose_move.assert_called_once_with( engine.mode, view, legal_moves, Rules.evaluate_move) engine._rules.execute_move.assert_called_once_with( engine._game, player, move) engine._game.deck.discard.assert_called_once_with(movecard) engine._rules.draw_again.assert_not_called() assert movecard not in player.hand assert replacementcard in player.hand
def test_play_next_adult_illegal(self): engine = TestEngine._create_engine(GameMode.ADULT) player = engine._game.players[PlayerColor.RED] pawn = player.pawns[0] view = Mock() movecard = player.hand[0] replacementcard = Card(999, CardType.CARD_APOLOGIES) move = Move(movecard, [Action(ActionType.MOVE_TO_START, Mock()) ]) # not found in legal_moves legal_moves = [ Move(movecard, [Action(ActionType.MOVE_TO_POSITION, pawn)]) ] engine._game.create_player_view = MagicMock(return_value=view) engine._rules.construct_legal_moves = MagicMock( return_value=legal_moves) engine._game.track = MagicMock() engine._game.deck.draw = MagicMock(return_value=replacementcard) engine._game.deck.discard = MagicMock() engine.characters[0].choose_move = MagicMock(return_value=move) engine._rules.execute_move = MagicMock() engine._rules.draw_again = MagicMock(return_value=False) engine.play_next() engine._game.create_player_view.assert_called_once_with( PlayerColor.RED) engine._rules.construct_legal_moves.assert_called_once_with(view, card=None) engine.characters[0].choose_move.assert_called_once_with( engine.mode, view, legal_moves, Rules.evaluate_move) engine._rules.execute_move.assert_called_once_with( engine._game, player, legal_moves[0]) # we choose random move engine._game.deck.discard.assert_called_once_with(movecard) engine._rules.draw_again.assert_called_once_with(movecard) assert movecard not in player.hand assert replacementcard in player.hand
def test_constructor(self): card = Card(0, CardType.CARD_12) assert card.id == 0 assert card.cardtype == CardType.CARD_12