Exemplo n.º 1
0
def test_random_actions_computes_valid_actions():
    """ Runs computation 100 times and expects that it returns valid actions in each run """
    card_factory = MazeCardFactory()
    orig_board = Board(create_maze(MAZE_STRING, card_factory), leftover_card=card_factory.create_instance("NE", 0))
    for _ in range(100):
        board = copy.deepcopy(orig_board)
        maze = board.maze
        piece = board.create_piece()
        piece.maze_card = maze[BoardLocation(0, 0)]
        game = Mock()
        game.get_enabled_shift_locations.return_value = board.shift_locations
        game.board = board
        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, move_location = computer_player.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
Exemplo n.º 2
0
def test_computer_player_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 computer makes a move.
    """
    card_factory = MazeCardFactory()
    board = Board(create_maze(MAZE_STRING, card_factory), leftover_card=card_factory.create_instance("NE", 0))
    piece = board.create_piece()
    piece.maze_card = board.maze[BoardLocation(3, 6)]
    game = Mock()
    game.get_enabled_shift_locations.return_value = board.shift_locations
    game.board = board
    computer_player = ComputerPlayer(library_binding_factory=Mock(), move_url="move-url", shift_url="shift-url",
                                     game=game, identifier=9, board=board, piece=piece)

    for _ in range(100):
        shift_action, move_location = computer_player.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
Exemplo n.º 3
0
def test_is_reachable_for_connected_neighbors():
    """ Tests is_reachable """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert graph.is_reachable(BoardLocation(2, 4), BoardLocation(1, 4))
    assert graph.is_reachable(BoardLocation(2, 4), BoardLocation(2, 3))
    assert graph.is_reachable(BoardLocation(2, 4), BoardLocation(3, 4))
Exemplo n.º 4
0
def param_tuple_to_param_dict(maze_string, leftover_out_paths, piece_starts,
                              objective):
    """ Converts a tuple of board state defining parameters to a dictionary,
    which can be used by create_board_and_pieces.

    :param maze_string: a string defining a maze
    :param leftover_out_paths: the out paths of the leftover maze card
    :param piece_starts: a list of starting locations of pieces on the board. The number of pieces will be equal to
    the size of this list. Each location is a 2-tuple.
    :param objective: the location (2-tuple) of the objective,
    or 'leftover' to denote that the objective is the leftover maze card
    """
    maze_card_factory = MazeCardFactory()
    maze = create_maze(maze_string, maze_card_factory)
    leftover_card = maze_card_factory.create_instance(leftover_out_paths, 0)
    param_dict = {
        "maze":
        maze,
        "leftover_card":
        leftover_card,
        "piece_locations":
        [BoardLocation(*piece_start) for piece_start in piece_starts]
    }
    if type(objective) == tuple:
        param_dict["objective_location"] = BoardLocation(*objective)
    elif objective == "leftover":
        param_dict["objective_maze_card"] = leftover_card
    return param_dict
Exemplo n.º 5
0
def test_reachable_locations():
    """ Tests reachable_locations """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    reachable = graph.reachable_locations(BoardLocation(0, 1))
    expected = {BoardLocation(*coord) for coord in [(0, 1), (0, 2), (0, 3), (1, 3)]}
    assert set(reachable) == expected
Exemplo n.º 6
0
def test_move_raises_error_on_unreachable_location():
    """ Tests move validation """
    maze_card_factory = MazeCardFactory()
    board = Board(maze=create_maze(MAZE_STRING, maze_card_factory),
                  leftover_card=maze_card_factory.create_random_maze_card())
    piece = board.create_piece()
    piece.maze_card = board.maze[BoardLocation(0, 1)]
    with pytest.raises(MoveUnreachableException):
        board.move(piece, BoardLocation(0, 0))
Exemplo n.º 7
0
def test_move_new_objective_locations_after_reaching_location():
    """ Tests new objective generation after reaching one """
    maze_card_factory = MazeCardFactory()
    maze = create_maze(MAZE_STRING, maze_card_factory)
    objective_maze_card = maze[BoardLocation(1, 6)]
    board = Board(maze=maze,
                  leftover_card=maze_card_factory.create_random_maze_card(),
                  objective_maze_card=objective_maze_card)
    piece = board.create_piece()
    piece.maze_card = maze[BoardLocation(0, 6)]
    board.move(piece, BoardLocation(1, 6))
    _assert_all_piece_and_objective_location_different(board)
Exemplo n.º 8
0
def test_move_updates_players_maze_card_correctly():
    """ Tests move
    Instead of calling init_board(), the board is built manually, and
    the player's position is set manually as well, so that
    randomness is eliminated for testing """
    maze_card_factory = MazeCardFactory()
    board = Board(maze=create_maze(MAZE_STRING, maze_card_factory),
                  leftover_card=maze_card_factory.create_random_maze_card())
    piece = board.create_piece()
    piece.maze_card = board.maze[BoardLocation(0, 1)]
    board.move(piece, BoardLocation(0, 2))
    assert board.maze[BoardLocation(0, 2)] == piece.maze_card
Exemplo n.º 9
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)
Exemplo n.º 10
0
def test_is_reachable_for_swapped_locations():
    """ Tests is_reachable. Re-runs all of the above tests with swapped locations. """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert not graph.is_reachable(BoardLocation(1, 0), BoardLocation(0, 0))
    assert not graph.is_reachable(BoardLocation(0, 1), BoardLocation(0, 0))
    assert not graph.is_reachable(BoardLocation(2, 5), BoardLocation(2, 4))

    assert graph.is_reachable(BoardLocation(1, 4), BoardLocation(2, 4))
    assert graph.is_reachable(BoardLocation(2, 3), BoardLocation(2, 4))
    assert graph.is_reachable(BoardLocation(3, 4), BoardLocation(2, 4))

    assert graph.is_reachable(BoardLocation(3, 2), BoardLocation(3, 1))

    assert graph.is_reachable(BoardLocation(5, 0), BoardLocation(1, 4))

    assert not graph.is_reachable(BoardLocation(4, 4), BoardLocation(1, 0))

    assert graph.is_reachable(BoardLocation(6, 3), BoardLocation(5, 0))
    assert graph.is_reachable(BoardLocation(2, 6), BoardLocation(0, 6))
Exemplo n.º 11
0
def test_computer_player_calls_start_on_compute_method(post_move, post_shift, time_sleep):
    """ Tests that the computer player calls start() one its computation method.
    """
    card_factory = MazeCardFactory()
    board = Board(create_maze(MAZE_STRING, card_factory), leftover_card=card_factory.create_instance("NE", 0))
    piece = board.create_piece()
    game = Mock()
    type(game).identifier = PropertyMock(return_value=7)
    game.get_enabled_shift_locations.return_value = board.shift_locations
    mock_method = Mock()
    mock_method.start = Mock()
    mock_method.shift_action = BoardLocation(0, 1), 90
    mock_method.move_action = board.maze.maze_card_location(piece.maze_card)
    mock_method_factory = Mock()
    mock_method_factory.return_value = mock_method
    player = ComputerPlayer(library_binding_factory=mock_method_factory, move_url="move-url", shift_url="shift-url",
                            game=game, identifier=9, board=board, piece=piece)
    player.run()
    mock_method.start.assert_called_once()
    post_shift.assert_called_once()
    post_move.assert_called_once()
Exemplo n.º 12
0
def test_create_fixed_maze_for_size_3():
    """ Creates a fixed maze of size 3 using a maze string.
    Checks every single position for correct layout. """
    maze = create_maze(maze_string_3)
    assert maze.maze_size == 3
    assert maze[BoardLocation(0, 0)].out_paths == MazeCard.T_JUNCT
    assert maze[BoardLocation(0, 0)].rotation == 0
    assert maze[BoardLocation(0, 1)].out_paths == MazeCard.CORNER
    assert maze[BoardLocation(0, 1)].rotation == 180
    assert maze[BoardLocation(0, 2)].out_paths == MazeCard.T_JUNCT
    assert maze[BoardLocation(0, 2)].rotation == 270
    assert maze[BoardLocation(1, 0)].out_paths == MazeCard.T_JUNCT
    assert maze[BoardLocation(1, 0)].rotation == 90
    assert maze[BoardLocation(1, 1)].out_paths == MazeCard.CROSS
    assert maze[BoardLocation(1, 2)].out_paths == MazeCard.STRAIGHT
    assert maze[BoardLocation(1, 2)].rotation == 0
    assert maze[BoardLocation(2, 0)].out_paths == MazeCard.CORNER
    assert maze[BoardLocation(2, 0)].rotation == 0
    assert maze[BoardLocation(2, 1)].out_paths == MazeCard.CORNER
    assert maze[BoardLocation(2, 1)].rotation == 270
    assert maze[BoardLocation(2, 2)].out_paths == MazeCard.STRAIGHT
    assert maze[BoardLocation(2, 2)].rotation == 90
Exemplo n.º 13
0
def create_board():
    card_factory = factory.MazeCardFactory()
    maze = factory.create_maze(MAZE_STRING, card_factory)
    leftover = card_factory.create_instance("NE", 0)
    return Board(maze=maze, leftover_card=leftover)
Exemplo n.º 14
0
def test_is_reachable_for_connected_neighbors_wo_direct_path():
    """ Tests is_reachable """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert graph.is_reachable(BoardLocation(3, 1), BoardLocation(3, 2))
Exemplo n.º 15
0
def test_is_reachable_for_connected_distant_cards():
    """ Tests is_reachable """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert graph.is_reachable(BoardLocation(1, 4), BoardLocation(5, 0))
Exemplo n.º 16
0
def test_is_reachable_for_unconnected_cards_with_only_one_wall():
    """ Tests is_reachable """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert not graph.is_reachable(BoardLocation(1, 0), BoardLocation(4, 4))
Exemplo n.º 17
0
def test_is_reachable_for_paths_on_border():
    """ Tests is_reachable """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert graph.is_reachable(BoardLocation(5, 0), BoardLocation(6, 3))
    assert graph.is_reachable(BoardLocation(0, 6), BoardLocation(2, 6))
Exemplo n.º 18
0
def create_board(maze_string=ALL_CONNECTED_3):
    maze = factories.create_maze(maze_string)
    return Board(maze=maze)
Exemplo n.º 19
0
def test_is_reachable_for_same_location():
    """ Tests is_reachable """
    maze = create_maze(MAZE_STRING)
    graph = Graph(maze)
    assert graph.is_reachable(BoardLocation(0, 0), BoardLocation(0, 0))