Esempio n. 1
0
def dto_to_game(game_dto):
    """ maps a DTO to a game
    to deserialize a persisted instance.

    :param game_dto: a dictionary representing the structure of the game,
    created by game_to_dto
    :return: a Game instance whose state is equal to the DTO
    """
    maze, leftover_card, maze_card_by_id = _dto_to_maze_cards_and_dictionary(
        game_dto[MAZE])
    objective_maze_card = maze_card_by_id[game_dto[OBJECTIVE]]
    board = Board(maze, leftover_card, objective_maze_card=objective_maze_card)
    players = [
        _dto_to_player(player_dto, board, maze_card_by_id)
        for player_dto in game_dto[PLAYERS]
    ]
    board._pieces = [player.piece for player in players]
    turns_prepare_delay = _dto_to_timedelta(game_dto[TURN_PREPARE_DELAY])
    turns = _dto_to_turns(game_dto[NEXT_ACTION],
                          players=players,
                          prepare_delay=turns_prepare_delay)
    identifier = game_dto[ID]
    game = Game(identifier, board=board, players=players, turns=turns)
    for player in players:
        player.set_game(game)
    game.previous_shift_location = _dto_to_board_location(
        game_dto[PREVIOUS_SHIFT_LOCATION])
    return game
Esempio n. 2
0
def create_game(maze_size=7, game_id=0, with_delay=True):
    """ Creates a game instance with a random board. Player and piece initialization
    is not done here. """
    if not with_delay:
        return Game(game_id, board=create_board(maze_size), turns=Turns())
    else:
        return Game(game_id, board=create_board(maze_size))
Esempio n. 3
0
def test_given_empty_game__when_player_is_added__initializes_turns():
    game = Game(identifier=0)

    player = Player(game.unused_player_id())
    game.add_player(player)

    game.turns.next_player_action() == PlayerAction(player,
                                                    PlayerAction.PREPARE_SHIFT)
Esempio n. 4
0
def test_get_enabled_shift_locations_with_previous_shift():
    """ Tests get_enabled_shift_locations where the previous shift is (3, 0) """
    board = Board()
    game = Game(identifier=0, board=board)
    game.previous_shift_location = BoardLocation(3, 0)
    expected_disabled = BoardLocation(3, board.maze.maze_size - 1)
    enabled_shift_locations = game.get_enabled_shift_locations()
    assert expected_disabled not in enabled_shift_locations
 def _setup(game_id, player_id):
     game = Game(game_id, turns=Turns())
     game.add_player(Player(player_id))
     game_repository = game_repository_coach.when_game_repository_find_by_id_then_return(
         game)
     game_repository.update = Mock()
     interactor = interactors.PlayerInteractor(
         game_repository=game_repository)
     return game, interactor
Esempio n. 6
0
def given_running_game__when_restart__then_turns_are_started():
    turns = Mock()
    game = Game(identifier=0, turns=turns)
    game.add_player(Player(0))
    turns.reset_mock()

    restart(game)

    turns.start.assert_called_once()
Esempio n. 7
0
def test_move_raises_error_on_invalid_player_id():
    """ Tests move validation """
    game = Game(identifier=0)
    player_id = game.unused_player_id()
    game.add_player(Player(player_id))
    game.start_game()
    with pytest.raises(PlayerNotFoundException):
        game.move(player_id - 1, BoardLocation(5, 5))
Esempio n. 8
0
def test_shift_raises_error_on_invalid_player_id():
    """ Tests shift validation """
    game = Game(identifier=0)
    player_id = game.unused_player_id()
    game.add_player(Player(player_id))
    game.start_game()
    with pytest.raises(PlayerNotFoundException):
        game.shift(player_id + 1, BoardLocation(0, 1), 90)
Esempio n. 9
0
def test_move_does_not_raise_error_after_shift():
    """ Tests turn validation """
    board = Mock()
    turns = Mock()
    turns.is_action_possible.return_value = True
    game = Game(identifier=0, board=board, turns=turns)
    player_id = game.unused_player_id()
    game.add_player(Player(player_id))
    game.start_game()
    player = game.get_player(player_id)
    game.move(player_id, BoardLocation(0, 0))
    board.move.assert_called_once()
    turns.is_action_possible.assert_called_once_with(player,
                                                     PlayerAction.MOVE_ACTION)
Esempio n. 10
0
def _create_test_game(with_computer=False):
    """ Creates a Game instance by hand """
    card_factory = MazeCardFactory()
    board = Board(leftover_card=MazeCard(0, MazeCard.T_JUNCT, 0))
    for row in range(board.maze.maze_size):
        for column in range(board.maze.maze_size):
            if row == 0 and column == 0:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.STRAIGHT, 0)
            elif row == 1 and column == 1:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.CORNER, 0)
            elif row == 2 and column == 2:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.T_JUNCT, 270)
            else:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.T_JUNCT, 0)
    player_ids = [3, 4]
    players = [
        Player(identifier=player_id, game=None) for player_id in player_ids
    ]
    if with_computer:
        player_ids.append(42)
        players.append(
            create_computer_player(player_id=42,
                                   compute_method="dynamic-foo",
                                   shift_url="shift-url",
                                   move_url="move-url"))
    for player in players:
        player.set_board(board)
    players[0].piece.maze_card = board.maze[BoardLocation(3, 3)]
    players[1].piece.maze_card = board.maze[BoardLocation(5, 5)]
    players[0].piece.piece_index = 1
    players[1].piece.piece_index = 0
    players[0].score = 7
    players[1].score = 8
    board._objective_maze_card = board.maze[BoardLocation(1, 4)]
    turns = Turns(players,
                  next_action=PlayerAction(players[1],
                                           PlayerAction.MOVE_ACTION))
    game = Game(identifier=7, turns=turns, board=board, players=players)
    for player in players:
        player._game = game
    game.previous_shift_location = BoardLocation(0, 3)
    return game, player_ids
Esempio n. 11
0
def test_player_reaches_objective_increase_score():
    """ Tests that the score on a player is increased once he reaches an objective """
    board = Mock()
    turns = Mock()
    turns.is_action_possible.return_value = True
    board.move.return_value = True
    game = Game(identifier=0, board=board, turns=turns)
    player_id = game.unused_player_id()
    game.add_player(Player(player_id))
    old_score = game.get_player(player_id).score
    game.move(player_id, BoardLocation(0, 1))
    assert game.get_player(player_id).score == old_score + 1
Esempio n. 12
0
def test_bot_random_algorith_when_piece_is_pushed_out(post_move, post_shift,
                                                      time_sleep):
    """ Tests case where piece is positioned on a shift location, so that it is pushed out.
    Runs computation 100 times. Push-out expectation rate is 1/12.
    Probability that no push-out takes place in 100 runs is negligible
    .start() is patched so that the compute method runs sequentially.
    This test recreates a bug, where the pushed-out piece is not updated correctly, leading
    to exceptions thrown when bot makes a move.
    """
    board = create_board()
    piece = board.create_piece()
    piece.maze_card = board.maze[BoardLocation(3, 6)]
    game = Game(0, board=board, turns=Turns())
    bot = Bot(library_binding_factory=Mock(),
              move_url="move-url",
              shift_url="shift-url",
              identifier=9,
              piece=piece)
    bot.set_game(game)

    for _ in range(100):
        shift_action, move_location = bot.random_actions()
        shift_location, _ = shift_action
        allowed_coordinates = [(3, 6)]
        if shift_location == BoardLocation(3, 6):
            allowed_coordinates = [(3, 5)]
        elif shift_location == BoardLocation(3, 0):
            allowed_coordinates = [(3, 0)]
        allowed_moves = {
            BoardLocation(*coordinates)
            for coordinates in allowed_coordinates
        }
        assert move_location in allowed_moves
Esempio n. 13
0
def test_random_actions_computes_valid_actions():
    """ Runs computation 100 times and expects that it returns valid actions in each run """
    orig_board = create_board()
    for _ in range(100):
        board = copy.deepcopy(orig_board)
        game = Game(0, board=board, turns=Turns())
        bot = Bot(library_binding_factory=Mock(),
                  move_url="move-url",
                  shift_url="shift-url",
                  identifier=9)
        bot.set_game(game)
        shift_action, move_location = bot.random_actions()
        shift_location, shift_rotation = shift_action
        assert shift_rotation in [0, 90, 180, 270]
        assert shift_location in board.shift_locations
        allowed_coordinates = [(0, 0)]
        if shift_location == BoardLocation(0, 1) and shift_rotation == 270:
            allowed_coordinates += [(0, 1)]
        elif shift_location == BoardLocation(0, 1) and shift_rotation == 180:
            allowed_coordinates += [(0, 1), (1, 1)]
        elif shift_location == BoardLocation(1, 0) and shift_rotation == 270:
            allowed_coordinates += [(1, 0)]
        elif shift_location == BoardLocation(1, 0) and shift_rotation == 0:
            allowed_coordinates += [(1, 0), (1, 1), (1, 2), (2, 1), (2, 2),
                                    (3, 1), (3, 2)]
        elif shift_location == BoardLocation(6, 1):
            allowed_coordinates += [(0, 1), (0, 2), (1, 1), (2, 1)]
        allowed_moves = {
            BoardLocation(*coordinates)
            for coordinates in allowed_coordinates
        }

        assert move_location in allowed_moves
Esempio n. 14
0
def test_random_actions_should_respect_no_pushback_rule():
    """ Runs computation 50 times and checks that none of the computed shifts reverts the previous shift action """

    card_factory = MazeCardFactory()
    orig_board = Board(create_maze(MAZE_STRING, card_factory), leftover_card=card_factory.create_instance("NE", 0))
    for _ in range(50):
        board = copy.deepcopy(orig_board)
        maze = board.maze
        piece = board.create_piece()
        piece.maze_card = maze[BoardLocation(0, 0)]
        game = Game(0, board=orig_board)
        game.previous_shift_location = BoardLocation(0, 3)
        computer_player = ComputerPlayer(library_binding_factory=Mock(), move_url="move-url", shift_url="shift-url",
                                         game=game, identifier=9, board=board, piece=piece)
        shift_action, _ = computer_player.random_actions()
        shift_location, _ = shift_action
        assert shift_location != BoardLocation(6, 3)
Esempio n. 15
0
 def _setup():
     game = Game(5, turns=Turns())
     game_repository = game_repository_coach.when_game_repository_find_by_id_then_return(
         game)
     game_repository.update = Mock()
     interactor = interactors.PlayerActionInteractor(
         game_repository=game_repository)
     return game, interactor, game_repository
Esempio n. 16
0
def test_replace_board():
    """ Tests replace_board. Asserts that score and all player locations are reset,
    and that it is the first player's turn
    """
    turns = Mock()
    game = Game(identifier=0, turns=turns)
    player_ids = []
    for _ in range(2):
        player_id = game.unused_player_id()
        game.add_player(Player(player_id))
        player_ids.append(player_id)
    players = list(map(game.get_player, player_ids))
    players[0].score = 11
    players[1].score = 22
    players[0].piece.maze_card = game.board.maze[BoardLocation(1, 1)]
    players[1].piece.maze_card = game.board.maze[BoardLocation(2, 2)]
    pieces = list(map(lambda player: player.piece, players))

    board = Mock()
    type(board).pieces = PropertyMock(return_value=pieces)
    turns.reset_mock()
    game.replace_board(board)

    board.create_piece.assert_has_calls([call(), call()])
    turns.start.assert_called_once()
    assert players[0].score == 0
    assert players[1].score == 0
Esempio n. 17
0
def given_game_and_player__when_set_game_on_player__creates_piece_for_player_on_board(
):
    board = create_board()
    game = Game(0, board=board)
    player = Player(0)

    player.set_game(game)

    assert player.piece in board.pieces
Esempio n. 18
0
def test_add_player_validation():
    """ Tests that adding more players than MAX_PLAYERS does not add another one """
    game = Game(identifier=0)
    for _ in range(game.MAX_PLAYERS):
        player_id = game.unused_player_id()
        game.add_player(Player(player_id))
    with pytest.raises(GameFullException):
        game.add_player(Player(42))
Esempio n. 19
0
def test_unused_player_id_returns_new_id():
    """ Tests unused_player_id """
    game = Game(identifier=0)
    game.add_player(Player(3))
    game.add_player(Player(7))
    game.add_player(Player(11))
    player_id = game.unused_player_id()
    assert player_id not in [player.identifier for player in game.players]
Esempio n. 20
0
def test_random_actions_should_respect_no_pushback_rule():
    """ Runs computation 50 times and checks that none of the computed shifts reverts the previous shift action """
    orig_board = create_board()
    for _ in range(50):
        board = copy.deepcopy(orig_board)
        maze = board.maze
        piece = board.create_piece()
        piece.maze_card = maze[BoardLocation(0, 0)]
        game = Game(0, board=board, turns=Turns())
        game.previous_shift_location = BoardLocation(0, 3)
        bot = Bot(library_binding_factory=Mock(),
                  move_url="move-url",
                  shift_url="shift-url",
                  identifier=9,
                  piece=piece)
        bot.set_game(game)
        shift_action, _ = bot.random_actions()
        shift_location, _ = shift_action
        assert shift_location != BoardLocation(6, 3)
Esempio n. 21
0
def given_game_with_two_players__when_restart__then_score_is_reset():
    game = Game(identifier=0)
    add_players(game, 2)
    game.players[0].score = 11
    game.players[1].score = 22

    restart(game)

    assert game.players[0].score == 0
    assert game.players[1].score == 0
Esempio n. 22
0
def given_game_player_with_piece_index_0_removed__when_restart__then_remaining_player_keeps_piece_index(
):
    game = Game(identifier=0)
    add_players(game, 2)
    remove_player_with_piece_index(game, 0)
    remaining_piece = game.players[0].piece

    restart(game)

    assert game.players[0].piece.piece_index == remaining_piece.piece_index
Esempio n. 23
0
def given_game_with_two_players__when_restart__then_players_keep_piece_index():
    game = Game(identifier=0)
    add_players(game, 2)
    old_player_pieces = {
        player.identifier: player.piece
        for player in game.players
    }

    restart(game)

    for player in game.players:
        expected_piece_index = old_player_pieces[player.identifier].piece_index
        assert player.piece.piece_index == expected_piece_index
Esempio n. 24
0
def test_add_player_start_game_calls_methods_on_turns():
    """ Tests add_player, start_game and Player """
    board = Board()
    turns = Mock()
    game = Game(identifier=0, board=board, turns=turns)
    for _ in range(4):
        player_id = game.unused_player_id()
        game.add_player(Player(player_id))
    game.start_game()
    expected_turn_calls = [call.init(game.players)] + [call.start()]
    assert turns.mock_calls[-2:] == expected_turn_calls
Esempio n. 25
0
def test_unused_player_id_raises_exception_on_full_game():
    """ Tests unused_player_id """
    game = Game(identifier=0)
    for _ in range(game.MAX_PLAYERS):
        player_id = game.unused_player_id()
        game.add_player(Player(player_id))
    with pytest.raises(GameFullException):
        player_id = game.unused_player_id()
Esempio n. 26
0
def test_add_player_with_duplicate_id_does_not_add():
    """ Tests add_player """
    game = Game(identifier=0)
    game.add_player(Player(1))
    other_player = Player(1)
    game.add_player(other_player)
    assert len(game.players) == 1
    assert other_player not in game.players
Esempio n. 27
0
def test_add_player_start_game_calls_methods_on_board():
    """ Tests add_player, start_game and Player """
    board = Board()
    turns = Mock()
    game = Game(identifier=0, board=board, turns=turns)
    with patch.object(board, 'create_piece',
                      wraps=board.create_piece) as board_create_piece:
        for _ in range(4):
            player_id = game.unused_player_id()
            game.add_player(Player(player_id))
        game.start_game()
        expected_board_calls = [
            call.create_piece(),
            call.create_piece(),
            call.create_piece(),
            call.create_piece()
        ]
        assert board_create_piece.mock_calls == expected_board_calls
Esempio n. 28
0
def test_get_enabled_shift_locations_without_previous_shift():
    """ Tests get_enabled_shift_locations where the previous shift is None """
    board = Board()
    game = Game(identifier=0, board=board)
    enabled_shift_locations = game.get_enabled_shift_locations()
    assert set(enabled_shift_locations) == set(board.shift_locations)
Esempio n. 29
0
def test_add_get_player():
    """ Tests add_player and get_player """
    game = Game(identifier=0)
    player = Player(7)
    game.add_player(player)
    assert game.get_player(7) is player
Esempio n. 30
0
def test_get_player_raises_exception_for_unknown_id():
    """ Tests get_player """
    game = Game(identifier=0)
    with pytest.raises(PlayerNotFoundException):
        game.get_player(0)