Example #1
0
def simulation(board, screen, clock, show):
    # Get the legal moves from current board state
    legal_moves = board.get_legal_moves()
    # Check if the game ended
    if board.checkmate or board.stalemate:
        # Return the correct result in a number
        if board.checkmate and board.white_move:
            print("Simulated Win Black")
            return -1
        elif board.checkmate and not board.white_move:
            print("Simulated Win White")
            return 1
        else:
            print("Simulated Draw")
            return 0

    else:
        # If not the simulation continues
        # Pick a random legal move
        random_move = find_random_move(legal_moves)
        # Check if something went wrong
        if random_move is None:
            raise Exception("Random move is None")
        # Make the move
        board.make_move(random_move)
        # Check if the move should be displayed
        if show:
            # Display the board based on the state, selected position and highlighted squares
            display_board(board, screen, (), [])

            # Pygame refresh
            p.display.flip()
            clock.tick(30)
        # Recursion until the game ends
        return simulation(board, screen, clock, show)
Example #2
0
def train_monte_carlo_tree(board, screen, clock, show=False):
    # Prepare the board and the images if the training games should be shown
    if show:
        load_images()
        # Display the board based on the state, selected position and highlighted squares
        display_board(board, screen, (), [])
        # Pygame refresh
        p.display.flip()
        clock.tick(30)
    # Number of iterations of the training
    training_cycles = 5000
    # Saving rate (How often the file should be saved
    saving_rate = 50
    # Iteration counter (for debug purposes)
    counter = 1
    # Iterate through the saving iterations
    for i in range(int(training_cycles / saving_rate)):
        # Open the file
        with open("mcts1.json", "r") as file:
            # Load the tree
            tree = json.load(file)
            # Iterate through training
            for j in range(saving_rate):
                # Select the best node (based on ucb value)
                node = selection(tree["start"], board, screen, clock, show)
                print("Selection completed")
                # Get the new expanded child
                child_index = expansion(node, board)
                print("Expansion completed")
                new_node = node["children"][child_index]
                # Simulate and get the result of the game
                result = simulation(board, screen, clock, show)
                print("Simulation completed")
                # Update the parent values and win rates
                backpropagation(result, tree["start"], new_node)
                print("Backpropagation completed")
                # Reset the board
                board.reset_board()
                # Update the counter
                print(str(counter) + "/" + str(training_cycles))
                counter += 1
        # Save the file
        with open("mcts1.json", "w") as file:
            json.dump(tree, file, indent=8)
        print("SAVED")

    # DEBUG the first moves and their visits
    most_explored = float("-inf")
    highest_win_rate = float("-inf")
    move_with_best_win_rate = None
    for child in tree["start"]["children"]:
        if child["visits"] > most_explored:
            most_explored = child["visits"]
        if (child["win"] / child["visits"]) > highest_win_rate:
            highest_win_rate = (child["win"] / child["visits"])
            move_with_best_win_rate = child

        print(str(child["move_history"]) + ": " + str(child["visits"]))
    print("most explored node was visited: " + str(most_explored) + " times")
    print("Highest win rate is " + str(highest_win_rate) + " at move " + str(move_with_best_win_rate["move_history"]))
Example #3
0
def selection(node, board, screen, clock, show):
    # Get the legal moves in current game state
    legal_moves = board.get_legal_moves()
    # Check if the node is not the first (there would not be any move to make)
    if len(node["move_history"]) != 0:
        # Get the move of the node
        move = notation_list_to_moves(node["move_history"])[-1]
        # Iterate through the legal moves
        for legal_move in legal_moves:
            # Check if the move is a legal move
            if move == legal_move:
                print("made move " + str(move_to_notation(legal_move)))
                # The legal move is made, because it has extra properties (e.g. pawn promotion or castling)
                # while the move converted from notation is a simple move without special booleans
                board.make_move(legal_move)
                # Check if the move should be displayed
                if show:
                    # Display the board based on the state, selected position and highlighted squares
                    display_board(board, screen, (), [])
                    # Pygame refresh
                    p.display.flip()
                    clock.tick(30)
    # Get new legal moves (the state changed)
    legal_moves = board.get_legal_moves()
    # Check if the current node has every possible child => if not then we stop the selection and expand
    if len(node["children"]) < len(legal_moves):
        print("Legal moves: " + str([move_to_notation(move) for move in legal_moves]))
        print("Length of children: " + str(len(node["children"])))
        print("Found something unexplored")
        return node

    # Get the child with the best ucb
    # Initially the max ucb is -infinity so there will be a node which is higher
    max_ucb = float("-inf")
    # Keeps track of the best child
    best_child = None
    # Iterate through all the children of the current node
    for child in node["children"]:
        # Get the ucb value of the current child
        current_ucb = ucb_val(child)
        # Check if there is a new best child
        if current_ucb > max_ucb:
            # If so, update the max ucb and the best child
            max_ucb = current_ucb
            best_child = child

    # Recursion until the case above
    return selection(best_child, board, screen, clock, show)
Example #4
0
    def test_display_shows_all_fields(self):

        with patch('sys.stdout', new=StringIO()) as fake_out:
            MainClass.display_board()
            self.assertEqual(fake_out.getvalue(), "1")
Example #5
0
#         return static_evaluation(board)


# board for testing double capture scenarios
test_board1 = [[0 for _ in range(8)] for _ in range(8)]
test_board1[0][7] = Piece((7, 0), False)
test_board1[1][2] = Piece((2, 1), False)
test_board1[1][6] = Piece((6, 1), False)
test_board1[2][1] = Piece((1, 2))
test_board1[2][5] = Piece((5, 2))
test_board1[4][5] = Piece((5, 4))
test_board1[2][3] = Piece((3, 2))
test_board1[4][3] = Piece((3, 4))
test_board1[6][3] = Piece((3, 6))

display_board(test_board1)


def piece_recursive_moves(board, piece):
    moves = piece.potential_moves(board)
    print(moves)
    # Base case - piece can make no moves or only non-capturing moves
    if moves == None:
        return []
    # Else if only non-capturing moves can be made return these
    elif moves[0] == False:
        return moves
    # Otherwise simulate capturing move for each possible capture
    for move in moves[1]:
        print(move)
        x, y = piece.x, piece.y