예제 #1
0
def test_is_legal_move_true_one_stone():
    """Check that a valid one stone move is legal.
    """
    board = Board()

    move = [(6, 2, 1), ()]
    assert board.is_legal_move(move)
예제 #2
0
def test_is_empty_space_filled():
    """Check that empty spaces are correctly identified.
    """
    board = Board()
    board.place_stone(position=(3, 3), colour=1)

    assert not board.is_empty_space(position=(3, 3))
예제 #3
0
def test_is_legal_move_false_two_stones_same_colour():
    """Check that a two stone move is illegal if the stones are the same colour.
    """
    board = Board()

    move = [(6, 2, 1), (6, 3, 1)]
    assert not board.is_legal_move(move)
예제 #4
0
def test_is_valid_space_valid():
    """Check that a valid space on a base 4 board isn't misclassified as an
    invalid space.
    """
    board = Board()

    assert board.is_valid_space((3, 3))
예제 #5
0
def test_is_valid_space_out_of_range():
    """Check that a position outside the range of the board array is classified
    as invalid.
    """
    board = Board()

    assert not board.is_valid_space((7, 2))
예제 #6
0
def test_is_legal_move_true_two_stones():
    """Check that a valid two stone move is legal.
    """
    board = Board()

    move = [(6, 2, 1), (6, 3, 2)]
    assert board.is_legal_move(move)
예제 #7
0
def test_remove_stone_invalid():
    """Check that the function raises an error when there is no stone to be
    removed.
    """
    board = Board()

    with pytest.raises(AssertionError):
        board.remove_stone(position=(3, 3))
예제 #8
0
def test_empty_spaces_empty():
    """Check that the correct number of empty spaces are returned for an empty
    board.
    """
    n = 4
    board = Board(size=n)

    empty_spaces = board.get_empty_spaces()
    assert len(empty_spaces) == 3 * n**2 - 3 * n + 1
예제 #9
0
def test_get_neighbours_center():
    """Check that the correct neighbours are returned for the central position.
    """
    board = Board()

    expected_neighbours = [(3, 2), (4, 2), (4, 3), (3, 4), (2, 4), (2, 3)]
    actual_neighbours = board.get_neighbours(position=(3, 3))

    assert len(actual_neighbours) == len(expected_neighbours)
    assert set(actual_neighbours) == set(expected_neighbours)
예제 #10
0
def test_get_neighbours_edge():
    """Check that the correct neighbours are returned for an edge position.
    """
    board = Board()

    expected_neighbours = [(3, 6), (3, 5), (4, 4), (5, 4)]
    actual_neighbours = board.get_neighbours(position=(4, 5))

    assert len(actual_neighbours) == len(expected_neighbours)
    assert set(actual_neighbours) == set(expected_neighbours)
예제 #11
0
def test_place_stone_invalid_position():
    """Check that an error is raised if the position is invalid (i.e. lies
    outside the board).
    """
    n = 4
    board = Board(size=n)

    with pytest.raises(AssertionError):
        position = (0, 0)
        board.place_stone(position, colour=1)
예제 #12
0
def test_is_legal_move_false_one_stone_non_empty_space():
    """Check that a one stone move is illegal if the space is not empty.
    """
    board = Board()

    # Initialise the board with a stone
    board.place_stone((6, 2), colour=1)

    move = [(6, 2, 1), ()]
    assert not board.is_legal_move(move)
예제 #13
0
def test_has_legal_moves_some():
    """Check the function correctly returns that there are legal moves when the
    board is not.
    """
    n = 4
    board = Board(size=n)

    # Add a stone to the board for good measure
    board.board_2d[3, 3] = 1

    assert board.has_legal_moves()
예제 #14
0
def test_empty_spaces_full():
    """Check that the correct number of empty spaces are returned for a
    full board.
    """
    n = 4
    board = Board(size=n)

    board.board_2d = np.ones(board.board_2d.shape)

    empty_spaces = board.get_empty_spaces()
    assert len(empty_spaces) == 0
예제 #15
0
def test_is_valid_space_invalid():
    """Check that all invalid spaces on a base 4 board are correctly identified
    as invalid.
    """
    board = Board()

    invalid_spaces = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (2, 0), (4, 6),
                      (5, 5), (5, 6), (6, 4), (6, 5), (6, 6)]

    for space in invalid_spaces:
        assert not board.is_valid_space(space)
예제 #16
0
def test_has_legal_moves_none():
    """Check the function correctly returns that there are no legal moves when
    the board is full.
    """
    n = 4
    board = Board(size=n)

    # Populate the board with stones of Colour 1
    board.board_2d = np.ones(board.board_2d.shape)

    assert not board.has_legal_moves()
예제 #17
0
def test_empty_spaces_partial():
    """Check that the correct number of empty spaces are returned for a
    partially filled board.
    """
    n = 4
    board = Board(size=n)

    board.board_2d[3, 3] = 1

    empty_spaces = board.get_empty_spaces()
    assert len(empty_spaces) == 3 * n**2 - 3 * n
예제 #18
0
def test_place_stone_valid():
    """Check that place_stone correctly updates the board state when the
    placement is valid.
    """
    n = 4
    board = Board(size=n)

    position = (6, 0)
    board.place_stone(position, colour=1)

    assert board.board_2d[position[1], position[0]] == 1
    assert np.count_nonzero(board.board_2d) == 1
예제 #19
0
def test_is_legal_move_false_two_stones_two_non_empty_spaces():
    """Check that a two stone move is illegal if both of the desired spaces are
    not empty.
    """
    board = Board()

    # Initialise the board with a stone
    board.place_stone((6, 2), colour=1)
    board.place_stone((6, 3), colour=1)

    move = [(6, 2, 1), (6, 3, 2)]
    assert not board.is_legal_move(move)
예제 #20
0
def test_build_move_map():
    """Check that the move map is being built correctly.
    """
    board = Board()

    # Player 0
    moves = board.get_legal_moves(player=0)
    assert len(board.move_map_player_0) == len(moves)
    assert all([type(v) == int for v in board.move_map_player_0.values()])
    assert all([type(k) == tuple for k in board.move_map_player_0.keys()])

    # Player 1
    moves = board.get_legal_moves(player=1)
    assert len(board.move_map_player_1) == len(moves)
    assert all([type(v) == int for v in board.move_map_player_1.values()])
    assert all([type(k) == tuple for k in board.move_map_player_1.keys()])
예제 #21
0
def test_get_legal_moves():
    """Check that the function generates all possible moves when the board is
    empty.
    """
    board = Board()

    empty_spaces = board.get_empty_spaces()
    legal_moves = board.get_legal_moves(player=0)

    for space in empty_spaces:
        q, r = space
        assert ((q, r, 1), ()) in legal_moves
        assert ((q, r, 2), ()) in legal_moves

    for (space1, space2) in permutations(empty_spaces, r=2):
        assert ((space1[0], space1[1], 1), (space2[0], space2[1],
                                            2)) in legal_moves
예제 #22
0
 def getInitBoard(self):
     """
     Returns:
         startBoard: The initial game board. Note that this is not the form that
         will be passed to the neural network, but the entire board class.
     """
     board = Board(self.size, self.score_target)
     return board
예제 #23
0
def test_remove_stone_valid():
    """Check that the function removes a stone from the board (when there is
    one present.
    """
    board = Board()
    board.place_stone(position=(3, 3), colour=1)
    board.remove_stone(position=(3, 3))

    assert board.is_empty_space(position=(3, 3))
예제 #24
0
def test_board_default():
    """Test the Board constructor with default parameter values.
    """
    board = Board()

    assert board.size == 4
    assert board.score_target == 15
    assert board.captures == [0, 0]
    assert board.colours == [(1, 2), (3, 4)]
    assert np.all(board.board_2d == 0)
    assert board.board_2d.shape == (7, 7)
예제 #25
0
def test_is_fenced_edge():
    """Check that the function correctly classifies a fenced bloom at the edge
    of the board.
    """
    board = Board()

    # Add a bloom
    bloom = [(6, 3), (5, 4)]
    for position in bloom:
        board.place_stone(position, colour=1)

    # Fence the bloom
    for position in bloom:
        neighbours = board.get_neighbours(position)
        for neighbour in neighbours:
            if board.is_empty_space(neighbour):
                board.place_stone(neighbour, colour=2)

    assert board.is_fenced(bloom)
예제 #26
0
def test_execute_move_no_captures():
    """Check that the function performs correctly for a situation where there
    are no captures.
    """
    board = Board()

    # Initialise the board with some stones
    board.place_stone((6, 2), colour=1)
    board.place_stone((6, 3), colour=3)
    board.place_stone((5, 4), colour=1)

    moves = [(5, 3, 3), (4, 4, 4)]
    board.execute_move(moves, player=1)

    assert board.board_2d[3, 5] == 3
    assert board.board_2d[4, 4] == 4
    assert board.captures == [0, 0]
예제 #27
0
def test_execute_move_one_capture():
    """Check that the function performs correctly for a situation where there
    is one stone captured.
    """
    board = Board()

    # Initialise the board with some stones
    board.place_stone((6, 2), colour=1)
    board.place_stone((6, 3), colour=3)
    board.place_stone((5, 4), colour=1)

    moves = [(5, 3, 2), (4, 4, 1)]
    board.execute_move(moves, player=0)

    assert board.board_2d[3, 5] == 2
    assert board.board_2d[4, 4] == 1
    assert board.captures == [1, 0]
예제 #28
0
def test_find_bloom_members():
    """Check that the function correctly identifies all members of a bloom.
    """
    board = Board()

    # Add a bloom
    board.place_stone(position=(3, 2), colour=1)
    board.place_stone(position=(3, 3), colour=1)
    board.place_stone(position=(3, 4), colour=1)
    board.place_stone(position=(4, 3), colour=1)

    # Add an additional neighbouring stone of a different colour (that is not
    # part of the bloom).
    board.place_stone(position=(4, 2), colour=2)

    expected_bloom = [(3, 2), (3, 3), (3, 4), (4, 3)]
    actual_bloom = board.find_bloom_members(bloom=set(),
                                            colour=1,
                                            position=(3, 2))

    assert len(actual_bloom) == len(expected_bloom)
    assert set(actual_bloom) == set(expected_bloom)
예제 #29
0
def test_place_stone_invalid_non_empty():
    """Check that an error is raised if the position is already filled.
    """
    n = 4
    board = Board(size=n)

    position = (6, 0)
    board.place_stone(position, colour=1)

    with pytest.raises(AssertionError):
        board.place_stone(position, colour=1)
예제 #30
0
def test_get_board_3d():
    """Check that the the 2D board representation is successfully converted into
    a 3D representation.
    """
    board = Board()

    # Place a few different colour stones on the board
    board.place_stone(position=(3, 0), colour=1)
    board.place_stone(position=(6, 0), colour=2)
    board.place_stone(position=(0, 6), colour=3)
    board.place_stone(position=(3, 6), colour=4)

    board_3d = board.get_board_3d()

    assert board_3d.shape == (4, 7, 7)
    assert np.count_nonzero(board_3d) == 4
    assert board_3d[0, 0, 3] == 1
    assert board_3d[1, 0, 6] == 1
    assert board_3d[2, 6, 0] == 1
    assert board_3d[3, 6, 3] == 1