def test_empty_game(self): for playercount in [2, 3, 4]: for color in list(PlayerColor)[:playercount]: game = Game(playercount=playercount) view = game.create_player_view(color) assert RewardCalculatorV1().calculate( view ) == 0 # score is always zero if all pawns are in start
def test_safe_zone(self): game = Game(playercount=4) game.players[PlayerColor.RED].pawns[0].position.move_to_safe( 4) # last safe square before home view = game.create_player_view(PlayerColor.RED) assert RewardCalculatorV1().calculate(view) == 222 for color in [PlayerColor.BLUE, PlayerColor.YELLOW, PlayerColor.GREEN]: view = game.create_player_view(color) assert RewardCalculatorV1().calculate( view) == 0 # score is always zero if all pawns are in start
def test_equivalent_state(self): game = Game(playercount=4) game.players[PlayerColor.RED].pawns[0].position.move_to_square(4) game.players[PlayerColor.YELLOW].pawns[0].position.move_to_square(34) game.players[PlayerColor.GREEN].pawns[0].position.move_to_square(49) game.players[PlayerColor.BLUE].pawns[0].position.move_to_square(19) for color in PlayerColor: view = game.create_player_view(color) assert RewardCalculatorV1().calculate( view ) == 0 # score is always zero if all players are equivalent
def test_track_no_player(self): game = Game(4) game.track("action") assert game.history[0].action == "action" assert game.history[0].color is None assert game.history[0].card is None assert game.history[0].timestamp <= DateTime.utcnow() assert game.players[PlayerColor.RED].turns == 0 assert game.players[PlayerColor.YELLOW].turns == 0 assert game.players[PlayerColor.BLUE].turns == 0 assert game.players[PlayerColor.GREEN].turns == 0
def test_track_with_color(self): game = Game(4) player = MagicMock(color=PlayerColor.RED) card = MagicMock(cardtype=CardType.CARD_12) game.track("action", player, card) assert game.history[0].action == "action" assert game.history[0].color is PlayerColor.RED assert game.history[0].card == CardType.CARD_12 assert game.history[0].timestamp <= DateTime.utcnow() assert game.players[PlayerColor.RED].turns == 1 assert game.players[PlayerColor.YELLOW].turns == 0 assert game.players[PlayerColor.BLUE].turns == 0 assert game.players[PlayerColor.GREEN].turns == 0
def test_constructor_3_players_standard(self): game = Game(3) assert len(game.players) == 3 assert len(game.history) == 0 for color in [PlayerColor.RED, PlayerColor.YELLOW, PlayerColor.GREEN]: assert game.players[color].color == color assert len(game.players[color].hand) == 0 assert game.deck is not None
def _fill_squares(start: int, end: int) -> Game: game = Game(playercount=4) square = 0 for pawn in range(4): for color in [PlayerColor.BLUE, PlayerColor.RED, PlayerColor.YELLOW, PlayerColor.GREEN]: if square + start <= end: game.players[color].pawns[pawn].position.move_to_square(square + start) square += 1 return game
def test_create_player_view(self): game = Game(4) game.players[PlayerColor.RED].hand.append(game.deck.draw()) game.players[PlayerColor.YELLOW].hand.append(game.deck.draw()) game.players[PlayerColor.GREEN].hand.append(game.deck.draw()) game.players[PlayerColor.BLUE].hand.append(game.deck.draw()) view = game.create_player_view(PlayerColor.RED) assert game.players[PlayerColor.RED] is not view.player assert game.players[PlayerColor.YELLOW] is not view.opponents[ PlayerColor.YELLOW] assert game.players[PlayerColor.RED] == view.player for color in [PlayerColor.YELLOW, PlayerColor.GREEN, PlayerColor.BLUE]: assert view.opponents[color].color == color assert len(view.opponents[color].hand) == 0 assert view.opponents[color].pawns == game.players[color].pawns
def test_arbitrary(self): game = Game(playercount=4) game.players[PlayerColor.RED].pawns[0].position.move_to_home() game.players[PlayerColor.RED].pawns[1].position.move_to_safe(0) game.players[PlayerColor.RED].pawns[2].position.move_to_square(6) game.players[PlayerColor.RED].pawns[3].position.move_to_square(10) game.players[PlayerColor.YELLOW].pawns[0].position.move_to_square(34) game.players[PlayerColor.YELLOW].pawns[1].position.move_to_square(32) game.players[PlayerColor.YELLOW].pawns[2].position.move_to_start() game.players[PlayerColor.YELLOW].pawns[3].position.move_to_home() game.players[PlayerColor.GREEN].pawns[0].position.move_to_start() game.players[PlayerColor.GREEN].pawns[1].position.move_to_start() game.players[PlayerColor.GREEN].pawns[2].position.move_to_square(59) game.players[PlayerColor.GREEN].pawns[3].position.move_to_start() game.players[PlayerColor.BLUE].pawns[0].position.move_to_start() game.players[PlayerColor.BLUE].pawns[1].position.move_to_start() game.players[PlayerColor.BLUE].pawns[2].position.move_to_start() game.players[PlayerColor.BLUE].pawns[3].position.move_to_start() view = game.create_player_view(PlayerColor.RED) assert RewardCalculatorV1().calculate(view) == 319 view = game.create_player_view(PlayerColor.YELLOW) assert RewardCalculatorV1().calculate(view) == 239 view = game.create_player_view(PlayerColor.GREEN) assert RewardCalculatorV1().calculate(view) == 0 view = game.create_player_view(PlayerColor.BLUE) assert RewardCalculatorV1().calculate(view) == 0
def test_completed_and_winner(self): game = Game(4) # move all but last pawn into home for all of the players; the game is not complete for player in game.players.values(): for i in range(PAWNS - 1): assert game.completed is False player.pawns[i].position.move_to_home() # move the final pawn to home for one player; now the game is complete game.players[PlayerColor.RED].pawns[PAWNS - 1].position.move_to_home() assert game.completed is True assert game.winner is game.players[PlayerColor.RED]
def _create_realistic_game(): """Create a realistic game with changes to the defaults for all types of values.""" game = Game(4) game.track("this happened") game.track("another thing", game.players[PlayerColor.RED]) card1 = game.deck.draw() card2 = game.deck.draw() game.deck.draw() # just throw it away game.deck.discard(card1) game.deck.discard(card2) game.players[PlayerColor.RED].pawns[0].position.move_to_square(32) game.players[PlayerColor.BLUE].pawns[2].position.move_to_home() game.players[PlayerColor.BLUE].hand.append(card1) game.players[PlayerColor.YELLOW].pawns[3].position.move_to_safe(1) game.players[PlayerColor.GREEN].pawns[1].position.move_to_square(19) game.players[PlayerColor.GREEN].hand.append(card2) return game
def test_create_player_view_invalid(self): game = Game(2) with pytest.raises(KeyError): game.create_player_view( PlayerColor.BLUE) # no blue player in 2-player game
def _fill_safe(start: int) -> Game: game = Game(playercount=4) for color in [PlayerColor.BLUE, PlayerColor.RED, PlayerColor.YELLOW, PlayerColor.GREEN]: for pawn in range(4): game.players[color].pawns[pawn].position.move_to_safe(pawn + start) return game
def render(unused_argv: List[str], stdout: IO[str], unused_stderr: IO[str]) -> None: """Render an empty board.""" game = Game(4) board = render_board(game) stdout.write("%s" % board)
def test_json_roundtrip(self): game = TestGame._create_realistic_game() data = game.to_json() copy = Game.from_json(data) assert copy == game
def test_started(self): game = Game(4) assert game.started is False game.track("whatever") assert game.started is True
def test_constructor_invalid_players(self): for playercount in [-2, -1, 0, 1, 5, 6]: with pytest.raises(ValueError): Game(playercount)
def test_empty_4_player_empty(self, data): game = Game(playercount=4) expected = data["empty4"] actual = render_board(game) assert expected == actual
def test_winner(self): game = Game(playercount=2) game.players[PlayerColor.RED].pawns[0].position.move_to_home() game.players[PlayerColor.RED].pawns[1].position.move_to_home() game.players[PlayerColor.RED].pawns[2].position.move_to_home() game.players[PlayerColor.RED].pawns[3].position.move_to_home() view = game.create_player_view(PlayerColor.RED) assert RewardCalculatorV1().calculate(view) == 400 for color in [PlayerColor.YELLOW]: view = game.create_player_view(color) assert RewardCalculatorV1().calculate( view) == 0 # score is always zero if all pawns are in start game = Game(playercount=3) game.players[PlayerColor.RED].pawns[0].position.move_to_home() game.players[PlayerColor.RED].pawns[1].position.move_to_home() game.players[PlayerColor.RED].pawns[2].position.move_to_home() game.players[PlayerColor.RED].pawns[3].position.move_to_home() view = game.create_player_view(PlayerColor.RED) assert RewardCalculatorV1().calculate(view) == 800 for color in [PlayerColor.YELLOW, PlayerColor.GREEN]: view = game.create_player_view(color) assert RewardCalculatorV1().calculate( view) == 0 # score is always zero if all pawns are in start game = Game(playercount=4) game.players[PlayerColor.RED].pawns[0].position.move_to_home() game.players[PlayerColor.RED].pawns[1].position.move_to_home() game.players[PlayerColor.RED].pawns[2].position.move_to_home() game.players[PlayerColor.RED].pawns[3].position.move_to_home() view = game.create_player_view(PlayerColor.RED) assert RewardCalculatorV1().calculate(view) == 1200 for color in [PlayerColor.YELLOW, PlayerColor.GREEN, PlayerColor.BLUE]: view = game.create_player_view(color) assert RewardCalculatorV1().calculate( view) == 0 # score is always zero if all pawns are in start