예제 #1
0
def test_get_symmetries():
    """Check that the function correctly creates six new reflected boards and
    policy vectors, one for each axis of symmetry.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    # Place stones
    board.place_stone(position=(3, 1), colour=1)
    board.place_stone(position=(5, 1), colour=2)
    board.place_stone(position=(3, 5), colour=3)
    board.place_stone(position=(1, 5), colour=4)

    # board.visualise(show_coords=True, title="Original")

    # Create a dummy policy vector
    pi = np.random.random_sample(game.getActionSize())

    profiler = Profiler()
    profiler.start()

    symmetrical_states = game.getSymmetries(board, pi)

    profiler.stop()
    print(profiler.output_text(unicode=True, color=True))

    assert len(symmetrical_states) == 24
    assert symmetrical_states[1][1][37] == pi[52]
    assert symmetrical_states[1][1][614] == pi[1277]

    assert all(
        [sum(x[1]) == pytest.approx(sum(pi)) for x in symmetrical_states])
예제 #2
0
def test_get_init_board():
    """Check that a new board is initialised correctly.
    """
    game = BloomsGame()
    board = game.getInitBoard()

    assert type(board) == Board
예제 #3
0
def test_get_game_ended_ongoing():
    """Check that the function correctly signals an ongoing game.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    assert game.getGameEnded(board, player=-1) == 0.0
예제 #4
0
def test_get_canonical_form_inversion():
    """Check that the board is inverted (i.e. Player -1 becomes Player 1 and
    vice-a-versa) when called for Player 1.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    # Place stones
    board.place_stone(position=(5, 1), colour=1)
    board.place_stone(position=(5, 2), colour=2)
    board.place_stone(position=(1, 4), colour=3)
    board.place_stone(position=(1, 5), colour=4)

    # Update captures
    board.captures = [5, 10]

    # Uncomment to visualise the inversion
    # board.visualise()

    board = game.getCanonicalForm(board, player=-1)

    assert board.board_2d[1, 5] == 3
    assert board.board_2d[2, 5] == 4
    assert board.board_2d[4, 1] == 1
    assert board.board_2d[5, 1] == 2

    assert board.captures == [10, 5]
예제 #5
0
def test_get_valid_moves():
    """Test that the valid moves vector is correctly built.
    """
    game = BloomsGame(size=4)
    board = game.getInitBoard()

    valid_moves = game.getValidMoves(board, player=-1)
    assert len(valid_moves) == game.getActionSize()
    assert np.all((valid_moves == 0) | (valid_moves == 1))
예제 #6
0
def test_get_game_ended_loss():
    """Check that the function correctly signals a loss.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    # Set the number of captures for Player 1 (i.e. the opponent) to 15
    board.captures[1] = 15

    assert game.getGameEnded(board, player=-1) == -1.0
예제 #7
0
def test_get_game_ended_win():
    """Check that the function correctly signals a win.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    # Set the number of captures for Player -1/0 to 15
    board.captures[0] = 15

    assert game.getGameEnded(board, player=-1) == 1.0
예제 #8
0
def test_get_game_ended_draw():
    """Check that the function correctly signals a draw.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    # Fill the board
    for position in board.get_empty_spaces():
        board.place_stone(position=position, colour=1)

    assert game.getGameEnded(board, player=-1) == pytest.approx(1e-4)
예제 #9
0
def test_get_next_state_valid_move():
    """Check that the board state is updated if a legal move is performed.
    """
    game = BloomsGame(size=4)
    board = game.getInitBoard()

    # Attempt a legal move
    player = -1
    move = ((6, 2, 2), ())
    move_idx = board.move_map_player_0[move]
    next_board, next_player = game.getNextState(board, player, action=move_idx)

    next_board.board_2d
    for r in range(next_board.board_2d.shape[0]):
        for q in range(next_board.board_2d.shape[1]):
            if (q == 6) and (r == 2):
                assert next_board.board_2d[r, q] == 2
            else:
                assert next_board.board_2d[r, q] == 0

    assert next_player == -player
예제 #10
0
def test_get_next_state_invalid_move():
    """Check that the original (i.e. unchanged) board state is returned if an
    invalid move is performed.
    """
    game = BloomsGame(size=4)
    board = game.getInitBoard()

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

    initial_board_array = board.get_board_3d()

    # Attempt an illegal move
    player = -1
    move = ((6, 2, 2), ())
    move_idx = board.move_map_player_0[move]
    next_board, next_player = game.getNextState(board, player, action=move_idx)

    post_move_board_array = next_board.get_board_3d()

    assert next_player == -player
    assert np.all(initial_board_array == post_move_board_array)
예제 #11
0
def test_get_canonical_form_no_inversion():
    """Check that the original board is returned when called for Player -1.
    """
    game = BloomsGame(size=4, score_target=15)
    board = game.getInitBoard()

    # Place stones
    board.place_stone(position=(5, 1), colour=1)
    board.place_stone(position=(5, 2), colour=2)
    board.place_stone(position=(1, 4), colour=3)
    board.place_stone(position=(1, 5), colour=4)

    # Update captures
    board.captures = [5, 10]

    board = game.getCanonicalForm(board, player=1)

    assert board.board_2d[1, 5] == 1
    assert board.board_2d[2, 5] == 2
    assert board.board_2d[4, 1] == 3
    assert board.board_2d[5, 1] == 4

    assert board.captures == [5, 10]