def run_tests():
    # Test board evaluation function.
    game = Latrunculi(8)
    minimax = Minimax(game)
    state = game.start_state()

    state.board[0][:2] = -2  # Simulate black losing 2 pieces.
    eval_w = minimax.evaluate_board(state, 1)
    state.player = not state.player  # Simulate black having the turn.
    eval_b = minimax.evaluate_board(state, 1)

    assertion.assert_equal(4, eval_w, "latrunculi evaluate board positive")
    assertion.assert_equal(-14, eval_b, "latrunculi evaluate board negative")

    # =================================
    game = Connect_Four(7)
    minimax = Minimax_CF(game)
    state = game.start_state()

    state.board[3:6, 1] = -1
    state.board[4:6, 2] = 1

    eval_w = minimax.evaluate_board(state, 0)
    state.player = not state.player  # Simulate black having the turn.
    eval_b = minimax.evaluate_board(state, 0)

    assertion.assert_equal(3, eval_w, "connect four evaluate board positive")
    assertion.assert_equal(-3, eval_b, "connect four evaluate board negative")
def run_tests():
    # Test Action ID.
    action1 = Action((1, 2), (3, 4))
    action2 = Action((0, 0), (3, 4))

    assertion.assert_equal(1234, action1.numeric(), "action numeric id 1234")
    assertion.assert_equal(34, action2.numeric(), "action numeric id 34")

    # =================================

    game = Latrunculi(8)
    state = game.start_state()
    dictionary = dict()
    dictionary[state.stringify()] = "wow"

    assertion.assert_equal("wow", dictionary[state.stringify()],
                           "state hashing")

    # =================================
    # Test self-play performance evaluation.
    game = Connect_Four(6)
    as_white = evaluate_against_ai(game, get_ai_algorithm("Random", game),
                                   get_ai_algorithm("Random", game), True, 5,
                                   Config, None)
    as_black = evaluate_against_ai(game, get_ai_algorithm("Random", game),
                                   get_ai_algorithm("Random", game), False, 5,
                                   Config, None)
    print(as_white)
    print(as_black)
def run_tests():
    # Test terminal state cases.

    # Test white wins.
    game = Othello(6)
    state = game.start_state()
    state.board[:4][:] = 1
    state.board[4:][:] = -1

    game_over = game.terminal_test(state)
    utility_w = game.utility(state, True)
    utility_b = game.utility(state, False)

    assertion.assert_true(game_over, "Terminal test - white wins")
    assertion.assert_equal(1, utility_w, "Utility - white wins")
    assertion.assert_equal(-1, utility_b, "Utility - black loses")

    # =================================
    # Test black wins.
    state = game.start_state()
    state.board[:2][:] = 1
    state.board[2:][:] = -1

    game_over = game.terminal_test(state)
    utility_w = game.utility(state, True)
    utility_b = game.utility(state, False)

    assertion.assert_true(game_over, "Terminal test - black wins")
    assertion.assert_equal(1, utility_b, "Utility - black wins")
    assertion.assert_equal(-1, utility_w, "Utility - white loses")

    # =================================
    # Test white wins by eliminating all black pieces.
    state = game.start_state()
    state.board[2, 2:4] = 1
    state.board[3, 2:4] = 1

    game_over = game.terminal_test(state)
    utility_w = game.utility(state, True)
    utility_b = game.utility(state, False)

    assertion.assert_true(game_over, "Terminal test2 - black wins")
    assertion.assert_equal(1, utility_w, "Utility2 - white wins")
    assertion.assert_equal(-1, utility_b, "Utility2 - black loses")

    # =================================
    # Test tie.
    state = game.start_state()
    state.board[:3][:] = 1
    state.board[3:][:] = -1

    game_over = game.terminal_test(state)
    utility_w = game.utility(state, True)
    utility_b = game.utility(state, False)

    assertion.assert_true(game_over, "Terminal test - tie")
    assertion.assert_equal(0, utility_w, "Utility - black draws")
    assertion.assert_equal(0, utility_b, "Utility - white draws")

    # =================================
    # Test pass move.
    state = game.start_state()
    state.board[3, 2:4] = 0

    actions_w = game.actions(state)
    result = game.result(state, actions_w[0])
    actions_b = game.actions(result)
    result = game.result(result, actions_b[0])
    game_over = game.terminal_test(state)

    assertion.assert_equal([Action((2, 1), None)], actions_w,
                           "Actions - one move")
    assertion.assert_equal([None], actions_b, "Actions - no moves black")
    assertion.assert_equal([None], game.actions(result),
                           "Actions - no moves white")
    assertion.assert_true(result.player, "Actions - pass switches turn")
def run_tests():
    # Test initial board setup.

    # Test correct board size.
    test_size = 8
    game = Latrunculi(test_size)
    state = game.start_state()
    assertion.assert_equal(test_size, state.board.shape[1], "correct board width")
    assertion.assert_equal(test_size, state.board.shape[0], "correct board height")

    # =================================
    # "Chess" distribution.
    # Test number of white and black pieces are equal, and is the correct amount.
    num_white = (state.board == 1).sum()
    num_black = (state.board == -1).sum()

    assertion.assert_equal(16, num_black, "number of black pieces chess formation")
    assertion.assert_equal(16, num_white, "number of white pieces chess formation")

    # =================================
    # Test piece list is correct.
    pieces_board = []
    it = np.nditer(state.board, flags=["multi_index"])
    while not it.finished:
        y, x = it.multi_index
        if it[0] == 1 or it[0] == -1:
            pieces_board.append((y, x))
        it.iternext()

    assertion.assert_all_equal(pieces_board, state.pieces, "correct pieces in piece list")

    # Random distribution.
    # Test number of white and black pieces are equal, and is the correct amount.
    game = Latrunculi(8, 432)
    state = game.start_state()
    num_white = (state.board == 1).sum()
    num_black = (state.board == -1).sum()

    assertion.assert_equal(16, num_black, "number of black pieces random")
    assertion.assert_equal(16, num_white, "number of white pieces random")

    # =================================
    # Test initial player turn is white.
    assertion.assert_true(game.player(state), "initial player turn")

    # =================================
    # Test terminal state methods.
    # Test terminal_test.
    game = Latrunculi(8)
    state = game.start_state()
    state.board[-3:][:] = 0 # Set white's pieces, except 1, to empty squares.
    state.board[-1][0] = 1

    assertion.assert_true(game.terminal_test(state), "terminal state true")

    # =================================
    # Test utility function.

    assertion.assert_equal(-1, game.utility(state, True), "utility white")
    assertion.assert_equal(1, game.utility(state, False), "utility black")

    # =================================
    # Test available actions for "Chess" formation.
    game = Latrunculi(5)
    state = game.start_state()

    legal_moves = [
        Action((3, 0), (2, 0)), Action((3, 1), (2, 1)), Action((3, 2), (2, 2)),
        Action((3, 3), (2, 3)), Action((3, 4), (2, 4)),
        Action((4, 0), (2, 0)), Action((4, 1), (2, 1)), Action((4, 2), (2, 2)),
        Action((4, 3), (2, 3)), Action((4, 4), (2, 4))
    ]

    assertion.assert_all_equal(legal_moves, game.actions(state), "legal moves white")

    # =================================
    # Test available actions for "random" board.
    game = Latrunculi(6, 5)
    state = game.start_state()
    state.player = not state.player

    legal_moves = [
        Action((0, 1), (1, 1)), Action((0, 2), (1, 2)),
        Action((1, 0), (2, 0)), Action((1, 0), (1, 1)),
        Action((1, 4), (2, 4)), Action((1, 4), (1, 3)), Action((1, 4), (0, 4)),
        Action((1, 5), (2, 5)), Action((1, 5), (1, 3)), Action((2, 1), (1, 1)),
        Action((2, 1), (2, 0)), Action((2, 1), (2, 2)), Action((5, 0), (4, 0)),
        Action((5, 2), (4, 2)), Action((5, 2), (5, 3)), Action((5, 4), (4, 4)),
        Action((5, 4), (5, 3)), Action((5, 4), (5, 5))
    ]

    assertion.assert_all_equal(legal_moves, game.actions(state), "legal random moves white")

    # =================================
    # Test result of action.
    # Test simple move.
    game = Latrunculi(5)
    state = game.start_state()

    result = game.result(state, Action((3, 0), (2, 0)))
    old_piece = state.board[3][0]
    old_vacant = state.board[2][0]
    new_vacant = result.board[3][0]
    new_piece = result.board[2][0]

    assertion.assert_true(old_piece == new_piece, "regular move piece moved")
    assertion.assert_true(old_vacant == new_vacant, "regular move piece absent")

    # =================================
    # Test jump.
    result = game.result(state, Action((4, 1), (2, 1)))
    old_piece = state.board[4][1]
    old_vacant = state.board[2][1]
    new_vacant = result.board[4][1]
    new_piece = result.board[2][1]

    assertion.assert_true(old_piece == new_piece, "jump move piece moved")
    assertion.assert_true(old_vacant == new_vacant, "jump move piece absent")

    # =================================
    # Test double jump.
    game = Latrunculi(6, 489)
    state = game.start_state()

    result = game.result(state, Action((4, 1), (4, 5)))
    old_piece = state.board[4][1]
    old_vacant = state.board[4][5]
    new_vacant = result.board[4][1]
    new_piece = result.board[4][5]

    assertion.assert_true(old_piece == new_piece, "double jump move piece moved")
    assertion.assert_true(old_vacant == new_vacant, "double jump move piece absent")

    # =================================
    # Test move causing piece to be captured.
    game = Latrunculi(5, 42)
    state = game.start_state()

    result_cb = game.result(state, Action((4, 3), (3, 3)))
    state.player = not state.player
    result_cw = game.result(state, Action((1, 0), (2, 0)))

    assertion.assert_equal(2, result_cw.board[2][1], "capture white piece")
    assertion.assert_equal(-2, result_cb.board[2][3], "capture black piece")

    # =================================
    # Test captured piece not being able to move.
    actions = game.actions(result_cw)

    cant_move = True
    for action in actions:
        cant_move = action.source != (2, 1) and cant_move

    assertion.assert_true(cant_move, "captured piece can't move")

    # =================================
    # Test move causing captured piece to be freed.
    result_cw.player = not result_cw.player
    result_cb.player = not result_cb.player

    # Move both pieces that are capturing another.
    result1 = game.result(result_cw, Action((2, 0), (1, 0)))
    result2 = game.result(result_cw, Action((2, 2), (3, 2)))
    result3 = game.result(result_cb, Action((1, 3), (0, 3)))
    result4 = game.result(result_cb, Action((3, 3), (4, 3)))

    assertion.assert_equal(1, result1.board[2][1], "move west frees captured piece")
    assertion.assert_equal(1, result2.board[2][1], "move east frees captured piece")
    assertion.assert_equal(-1, result3.board[2][3], "move north frees captured piece")
    assertion.assert_equal(-1, result4.board[2][3], "move south frees captured piece")

    # =================================
    # Test capture causing captured piece to be freed.
    game = Latrunculi(5, 302)
    state = game.start_state()

    result1 = game.result(state, Action((3, 4), (3, 3))) # Capture black piece.
    result2 = game.result(result1, Action((1, 3), (2, 3))) # Free that piece.

    assertion.assert_equal(-2, result1.board[3][2], "captured black piece for freeing")
    assertion.assert_equal(-1, result2.board[3][2], "free piece by capture")

    # =================================
    # Test potential capture causing move not being possible.
    game = Latrunculi(8, 31)
    state = game.start_state()
    state.player = not state.player

    actions = game.actions(state)

    cant_move = True
    for action in actions:
        cant_move = action.dest != (3, 2) and cant_move

    assertion.assert_true(cant_move, "suicide can't move")

    # =================================
    # Test suicide move, a move that would normally result in capture,
    # but instead captures one of the two enemy pieces.

    # Test south
    game = Latrunculi(8, 42)
    state = game.start_state()
    state.player = not state.player

    exists = Action((6, 1), (7, 1)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move south")

    # =================================
    # Test south again
    game = Latrunculi(8, 107)
    state = game.start_state()
    state.player = not state.player

    exists = Action((3, 2), (4, 2)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move south 2")

    # =================================
    # Test south again again
    game = Latrunculi(8, 75)
    state = game.start_state()

    exists = Action((0, 2), (1, 2)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move south 3")

    # =================================
    # Test west
    game = Latrunculi(8, 96)
    state = game.start_state()

    exists = Action((3, 3), (3, 2)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move west")

    # =================================
    # Test west again
    game = Latrunculi(8, 118)
    state = game.start_state()

    exists = Action((3, 7), (3, 6)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move west 2")

    # =================================
    # Test east
    game = Latrunculi(8, 102)
    state = game.start_state()

    exists = Action((2, 1), (2, 2)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move east")

    # =================================
    # Test east again
    game = Latrunculi(8, 77)
    state = game.start_state()

    exists = Action((1, 1), (1, 2)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move east 2")

    # =================================
    # Test north
    game = Latrunculi(8, 118)
    state = game.start_state()

    exists = Action((6, 3), (5, 3)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move north")

    # =================================
    # Test north again
    game = Latrunculi(8, 70)
    state = game.start_state()

    exists = Action((6, 3), (5, 3)) in game.actions(state)

    assertion.assert_true(exists, "regular suicide move north 2")

    # =================================
    # Test potential capture causign move not being possible.
    game = Latrunculi(8, 69)
    state = game.start_state()
    state.player = not state.player

    exists = Action((1, 2), (3, 2)) in game.actions(state)

    assertion.assert_true(exists, "jump suicide move")

    # =================================
    # Test chump jain being broken, by potential capture.
    new_state = game.result(state, Action((1, 2), (3, 2)))
def run_tests():
    # Test possible initial actions.
    test_size = 6
    game = Connect_Four(test_size)
    state = game.start_state()

    expected_actions = [
        Action(None, (test_size - 1, 0)),
        Action(None, (test_size - 1, 1)),
        Action(None, (test_size - 1, 2)),
        Action(None, (test_size - 1, 3)),
        Action(None, (test_size - 1, 4)),
        Action(None, (test_size - 1, 5))
    ]

    assertion.assert_all_equal(expected_actions, game.actions(state),
                               "correct actions")
    # =================================
    # Test possible mid-game actions.
    result = game.result(state, Action(None, (test_size - 1, 0)))
    result = game.result(result, Action(None, (test_size - 1, 2)))
    result = game.result(result, Action(None, (test_size - 2, 0)))

    expected_actions = [
        Action(None, (test_size - 3, 0)),
        Action(None, (test_size - 1, 1)),
        Action(None, (test_size - 2, 2)),
        Action(None, (test_size - 1, 3)),
        Action(None, (test_size - 1, 4)),
        Action(None, (test_size - 1, 5))
    ]

    assertion.assert_all_equal(expected_actions, game.actions(result),
                               "correct actions moved")

    # =================================
    # Test terminal state vertical.

    result.player = not result.player
    result = game.result(result, Action(None, (test_size - 3, 0)))
    result.player = not result.player
    result = game.result(result, Action(None, (test_size - 4, 0)))

    assertion.assert_true(game.terminal_test(result), "terminal test vertical")

    # =================================
    # Test utility function.
    utility_w = game.utility(result, True)
    utility_b = game.utility(result, False)

    assertion.assert_equal(1, utility_w, "utility white")
    assertion.assert_equal(-1, utility_b, "utility black")

    # =================================
    # Test policy normalization.
    logits = np.array([
        -0.42,
        0.23,
        -0.33,
        0.23,
        -0.11,
        0.19,
        -0.42,
        0.23,
        -0.33,
        0.23,
        -0.11,
        0.19,
        -0.42,
        0.23,
        -0.33,
        0.23,
        -0.11,
        0.19,
        -0.42,
        0.23,
        -0.33,
        0.23,
        -0.11,
        0.19,
        -0.42,
        0.23,
        -0.33,
        0.23,
        -0.11,
        0.19,
        -0.42,
        0.23,
        -0.33,
        0.23,
        -0.11,
        0.19,
    ])
    state = game.start_state()
    mapping = game.map_actions(game.actions(state), logits)
Beispiel #6
0
def run_tests():
    # Test single input shape.
    game = Othello(6)
    network = NeuralNetwork(game)
    
    state = game.start_state()
    shape = network.shape_input(game.structure_data(state))

    assertion.assert_equal((1, 2, 6, 6), shape.shape, "Single input shape")

    # =================================
    # Test multiple inputs shape.
    state1 = game.start_state()
    state2 = game.result(state1, game.actions(state1)[0])
    state3 = game.result(state1, game.actions(state1)[1])

    in1 = game.structure_data(state1)
    in2 = game.structure_data(state2)
    in3 = game.structure_data(state3)
    shape = network.shape_input(array([in1, in2, in3]))

    assertion.assert_equal((3, 2, 6, 6), shape.shape, "Multiple inputs shape")

    # =================================
    # Test output shape of single input.

    policy, value = network.evaluate(in1)

    assertion.assert_equal((1, 36), policy.shape, "One input - policy shape")
    assertion.assert_equal((1, 1), value.shape, "One input - value shape")

    # =================================
    # Test output shape of multiple inputs.

    policies, values = network.evaluate(array([in1, in2, in3]))
    print(values)

    assertion.assert_equal((3, 36), policies.shape, "Multiple inputs - policy shape")
    assertion.assert_equal((3, 1), values.shape, "Multiple inputs - value shape")
    assertion.assert_equal(policies[0][0], policy[0][0], "Multiple and single policy equal")
    assertion.assert_equal(value[0][0], value[0][0], "Multiple and single value equal")
def run_tests():
    # Test softmax sampling.
    game = Othello(8)

    mcts = MCTS(game)
    state = game.start_state()

    actions = game.actions(state)
    root = Node(state, None)
    probs = [0.08, 0.09, 0.5, 0.4]
    visits = [6, 6, 98, 90]
    root.children = {a: Node(game.result(state, a), a, p, root) for (a, p) in zip(actions, probs)}
    for i, n in enumerate(root.children.values()):
        n.visits = visits[i]
        n.value = visits

    nodes = [n for n in root.children.values()]
    sampling = softmax_sample(nodes, [n.visits for n in nodes], 1.7)
    print(f"Softmax sampling: {sampling}")

    # =================================
    # Test selection.
    # Test first selection.
    probabilities = [0.2, 0.4, 0.1, 0.6]
    child_nodes = {action: Node(game.result(state, action), action, prob, root) for action, prob in zip(actions, probabilities)}
    root.children = child_nodes
    node = mcts.select(root)

    assertion.assert_equal(child_nodes[actions[0]], node, "first selection")

    # =================================
    # Test prior selection.
    root.visits = 3
    for child in child_nodes.values():
        child.value = 2
        child.visits = 3

    node = mcts.select(root)

    assertion.assert_equal(child_nodes[actions[3]], node, "prior selection")

    # =================================
    # Test exploration of less visited node.
    root.visits = 3
    for child in child_nodes:
        child.value = 4
        child.visits = 3

    child_nodes[3].value = 3
    child_nodes[3].visits = 2
    node = mcts.select(root)

    assertion.assert_equal(child_nodes[3], node, "exploration selection")

    # =================================
    # Test expansion.
    # Test correct number of children.
    root = Node(state, None)
    mcts.expand(root, actions)

    assertion.assert_equal(16, len(root.children), "expansion correct num of children")

    # =================================
    # Test correct parent
    parent_is_root = True
    for child in root.children:
        parent_is_root = child.parent == root and parent_is_root

    assertion.assert_true(parent_is_root, "expansion correct parent")