def main():
    board = HexBoard(2)
    num_of_cells = board.get_board_size() * board.get_board_size()
    for nc in range(int(num_of_cells / 2)):
        ## Just a small heuristic for opening strategy, you can test this if you want. But then you have to comment the move_blue below out too
        # if board.size % 2 != 0 and len(board.get_move_list()) == len(board.get_all_vertices()): # If it's the first move and the board is uneven
        #     move_blue = (board.size // 2, board.size // 2) # Always place the first move in the middle
        # else:
        # move_blue = ab.alphabeta_move(board, depth=2, is_max=True)

        move_blue = ab.alphabeta_move(board, depth=4, is_max=True)
        #move_blue = ab.alphabeta_move_Id(board, is_max=True, show_AI=True)
        board = ab._update_board(board, move_blue, is_max=True)
        board.print()
        if board.is_game_over(
        ):  # TODO: add condition for game over without no winning (board full)
            print("==== BLUE WINS ====")
            board.print()
            # break
            return "blue"
        move_red = ab.alphabeta_move(board, depth=2, is_max=True)
        #move_red = ab.alphabeta_move_Id(board, is_max=True, show_AI=True)
        board = ab._update_board(
            board, move_red, is_max=False
        )  # Using false here and true for the alphabeta is a bit confusing, but we need it to make moves for red here.
        board.print()
        if board.is_game_over(
        ):  # TODO: add condition for game over without no winning (board full)
            print("==== RED WINS ====")
            board.print()
            # break
            return "red"
Exemplo n.º 2
0
def mcts_mcts(cp1, N1, cp2, N2, size, print_all=False, first=True):
    #mcts plays with mcts
    Game = HexBoard(size)
    A1_color = 1
    A2_color = 2
    root = Tree(Game, color=A2_color, parent=None, coordinate=None)
    if print_all:
        if first == True:
            print('First move (blue) is mcts')
            print('Second move (red) is mcts')
        else:
            print('First move (blue) is mcts')
            print('Second move (red) is mcts')

    while not Game.is_game_over():
        if first == True:
            #mcts moves first
            A1_move = monte_carlo_tree_search(root, cp=cp1, N=N1)
        else:
            A1_move = monte_carlo_tree_search(root, cp=cp2, N=N2)
        Game.place(coordinates=A1_move.location, color=A1_color)
        if Game.is_game_over():
            if print_all:
                Game.print()
            if first == True:
                #if method1 win, return True
                return Game.check_win(A1_color)
            else:
                #if method1 win, return True
                return Game.check_win(A2_color)
        else:
            root = Tree(Game,
                        color=A1_color,
                        parent=None,
                        coordinate=A1_move.location)
            if first == True:
                A2_move = monte_carlo_tree_search(root, cp=cp2, N=N2)
            else:
                A2_move = monte_carlo_tree_search(root, cp=cp1, N=N1)
            Game.place(coordinates=A2_move.location, color=A2_move.color)
            root = Tree(Game,
                        color=A2_color,
                        parent=None,
                        coordinate=A2_move.location)
    if print_all:
        Game.print()

    if first == True:
        #if method1 win or not
        return Game.check_win(A1_color)
    else:
        return Game.check_win(A2_color)
def alphabeta_Id(board: HexBoard, depth: int, alpha: float, beta: float,
                 is_max: bool) -> float:
    # board.print()
    print("in alphabeta_Id000000000")
    try:
        (hit, g, ttbm) = transposition_table.lookup(board,
                                                    board.get_board_size(),
                                                    depth)
        print("in alphabeta_Id", hit, g, ttbm)
    except Exception as e:  #
        print('Exception in running lookup function: ' + str(e))
    if hit():
        return g

    if depth == 0 or board.is_game_over():
        g = dijkstra_eval(board)
        bm = ()

    legals = board.get_move_list()
    if legals:
        if is_max:
            g: float = -_INF

            for move in ttbm + legals:
                updated_board: HexBoard = _update_board(
                    board, move, is_max)  # y do we make the move first?
                gc = alphabeta_Id(updated_board, depth - 1, alpha, beta,
                                  is_max)
                if gc > g:
                    bm = updated_board
                    g = gc

                alpha = max(alpha, g)
                if beta <= alpha:
                    break

        else:  # if is_max False
            g: float = _INF

            for move in ttbm + legals:
                updated_board: HexBoard = _update_board(board, move, is_max)
                gc = alphabeta_Id(updated_board, depth - 1, alpha, beta,
                                  is_max)
                if gc < g:
                    bm = updated_board
                    g = gc

                beta = min(beta, g)
                if beta <= alpha:
                    break
        transposition_table.store(updated_board,
                                  updated_board.get_board_size(), g, depth, bm)
        return g

    else:
        print("NO MORE LEGAL MOVES LEFT")
        return dijkstra_eval(board)
def alphabeta(board: HexBoard, depth: int, alpha: float, beta: float,
              is_max: bool) -> float:
    # board.print()
    if depth == 0 or board.is_game_over():
        return dijkstra_eval(board)

    legals = board.get_move_list()
    if legals:

        if is_max:
            g: float = -_INF

            for move in legals:
                updated_board: HexBoard = _update_board(board, move, is_max)
                g = max(
                    g,
                    alphabeta(updated_board,
                              depth - 1,
                              alpha,
                              beta,
                              is_max=False))

                alpha = max(alpha, g)
                if beta <= alpha:
                    break

        else:
            g: float = _INF

            for move in legals:
                updated_board: HexBoard = _update_board(board, move, is_max)
                g = min(
                    g,
                    alphabeta(updated_board,
                              depth - 1,
                              alpha,
                              beta,
                              is_max=True))

                beta = min(beta, g)
                if beta <= alpha:
                    break

        return g

    else:
        print("NO MORE LEGAL MOVES LEFT")
        return dijkstra_eval(board)
def minimax(board: HexBoard, depth: int, is_max: bool) -> float:

    if depth == 0 or board.is_game_over():
        board.print()
        return dijkstra_eval(board)

    legals = board.get_move_list()
    if legals:

        if is_max:
            g: float = -_INF

            for move in legals:
                updated_board: HexBoard = _update_board(board, move, is_max)
                g = max(g, minimax(updated_board, depth - 1, not is_max))

        else:
            g: float = _INF

            for move in legals:
                updated_board: HexBoard = _update_board(board, move, is_max)
                g = min(g, minimax(updated_board, depth - 1, not is_max))

        return g
Exemplo n.º 6
0
def human_compu(algor, method='random', depth=3):
    """A function that human play with computer, user can choose their prefered
    board size(3,4 recommanded), color, want to take first move"""
    global flag, INF, n_nodes, cutoff, Game, size

    print('Choose a board size:')
    size = int(input())
    Game = HexBoard(size)
    print('Choose a color: 1(BLUE) or 2(RED)')
    print('Blue: from left to right; Red: from top to bottom')
    opp_color = int(input())
    my_color = Game.get_opposite_color(opp_color)
    print('Do you want to start first? Yes(y) or No(n)')
    first = input()
    print('Game start!')
    # human first move do or not
    if first == 'y' or first == 'Yes':
        Game.print()
        x, y = xy_read(Game)
        Game.place(coordinates=(x, y), color=opp_color)
        Game.print()
        root = Tree(Game,
                    color=opp_color,
                    parent=None,
                    coordinate=(x, y),
                    my_color=my_color)

    else:
        first_color = my_color
        last_color = opp_color
        root = Tree(Game,
                    color=opp_color,
                    parent=None,
                    coordinate=None,
                    my_color=my_color)

    INF = 99999  # sufficient large number

    # human and computer play the game until one of them win
    while not Game.is_game_over():
        if algor == 'alphabeta':
            # varibales intialization
            n_nodes = 0
            cutoff = 0
            flag = 0
            my_move = alphabeta(n=root,
                                a=-INF,
                                b=INF,
                                d=depth,
                                method=method,
                                depth=depth,
                                my_color=my_color,
                                opp_color=opp_color)
            print('n_nodes=', n_nodes, '\n cutoff=', cutoff)

        elif algor == 'idtt':
            flag = 0
            transpositiontable = []
            n_nodes = 0
            cutoff = 0
            my_move = iterativedeepening(n=root,
                                         a=-INF,
                                         b=INF,
                                         DEPTH_stop=5,
                                         time_limit=5,
                                         my_color=my_color,
                                         opp_color=opp_color)
            print('n_nodes=', n_nodes, '\n cutoff=', cutoff)

        elif algor == "mcts":
            my_move = monte_carlo_tree_search(root, cp=1, N=1000)

        # retunred variable "my_move" is a node and contains info about computer's next step
        Game.place(coordinates=my_move.location, color=my_move.color)
        Game.print()

        if Game.is_game_over():
            break
        else:
            # read human's next move
            x, y = xy_read(Game)
            Game.place(coordinates=(x, y), color=opp_color)
            Game.print()
            root = Tree(Game,
                        color=opp_color,
                        parent=None,
                        coordinate=(x, y),
                        my_color=my_color)

    if Game.check_win(opp_color):
        print('Game over! You win :-)')
    else:
        print('Game over! You lose :-(')
Exemplo n.º 7
0
def mcts_alphabeta(cp=1,
                   N=500,
                   method='dijkstra',
                   depth=3,
                   size=3,
                   print_all=False,
                   first=True,
                   time_limit=5):
    #mcts plays with method
    #method='dijkstra' or 'idtt'
    global flag, user_color, unuse_color, INF, n_nodes, cutoff
    Game = HexBoard(size)
    A1_color = 1
    A2_color = 2
    root = Tree(Game,
                color=A2_color,
                parent=None,
                coordinate=None,
                my_color=A1_color)
    if print_all:
        if first == True:
            print('First move (blue) is mcts')
            print('Second move (red) is ' + method)
        else:
            print('First move (blue) is ' + method)
            print('Second move (red) is mcts')

    while not Game.is_game_over():
        INF = 99999
        flag = 0
        n_nodes = 0
        cutoff = 0
        if first == True:
            #mcts moves first
            A1_move = monte_carlo_tree_search(root, cp=cp, N=N)
        else:
            #method moves first
            if method == 'dijkstra':
                A1_move = alphabeta(n=root,
                                    a=-INF,
                                    b=INF,
                                    d=depth,
                                    method=method,
                                    depth=depth,
                                    my_color=A1_color,
                                    opp_color=A2_color)
            elif method == 'idtt':
                A1_move = iterativedeepening(n=root,
                                             a=-INF,
                                             b=INF,
                                             DEPTH_stop=depth,
                                             time_limit=time_limit,
                                             my_color=A1_color,
                                             opp_color=A2_color)
        Game.place(coordinates=A1_move.location, color=A1_color)
        if Game.is_game_over():
            if print_all:
                Game.print()
            if first == True:
                #if method1 win, return True
                return Game.check_win(A1_color)
            else:
                #if method1 win, return True
                return Game.check_win(A2_color)
        else:
            root = Tree(Game,
                        color=A1_color,
                        parent=None,
                        coordinate=A1_move.location,
                        my_color=A2_color)
            flag = 0
            n_nodes = 0
            cutoff = 0
            if first == True:
                if method == 'idtt':
                    A2_move = iterativedeepening(n=root,
                                                 a=-INF,
                                                 b=INF,
                                                 DEPTH_stop=depth,
                                                 time_limit=time_limit,
                                                 my_color=A2_color,
                                                 opp_color=A1_color)
                elif method == 'dijkstra':
                    A2_move = alphabeta(n=root,
                                        a=-INF,
                                        b=INF,
                                        d=depth,
                                        method=method,
                                        depth=depth,
                                        my_color=A2_color,
                                        opp_color=A1_color)
            else:
                A2_move = monte_carlo_tree_search(root, cp=cp, N=N)
            Game.place(coordinates=A2_move.location, color=A2_move.color)
            root = Tree(Game,
                        color=A2_color,
                        parent=None,
                        coordinate=A2_move.location,
                        my_color=A1_color)
    if print_all:
        Game.print()

    if first == True:
        #if method1 win or not
        return Game.check_win(A1_color)
    else:
        return Game.check_win(A2_color)
Exemplo n.º 8
0
def idtt_alphabeta(method='random',
                   idtt_depth=3,
                   depth2=3,
                   size=3,
                   print_all=False,
                   first=True,
                   time_limit=5):
    #idtt against alphabeta (random or dijkstra)
    #idtt_depth is idtt's depth; depth2 is method's deptth
    #first determins which moves first
    global flag, INF, n_nodes, cutoff
    Game = HexBoard(size)
    #firt move color=A1_color: blue
    A1_color = 1
    #second move color=A1_color: red
    A2_color = 2
    root = Tree(Game,
                color=A2_color,
                parent=None,
                coordinate=None,
                my_color=A1_color)
    if print_all:
        if first == True:
            print('First move (blue) is idtt')
            print('Second move (red) is ' + method)
        else:
            print('First move (blue) is ' + method)
            print('Second move (red) is idtt')

    while not Game.is_game_over():
        INF = 99999
        flag = 0
        n_nodes = 0
        cutoff = 0
        if first == True:
            #idtt moves first
            A1_move = iterativedeepening(n=root,
                                         a=-INF,
                                         b=INF,
                                         DEPTH_stop=idtt_depth,
                                         time_limit=time_limit,
                                         my_color=A1_color,
                                         opp_color=A2_color)
        else:
            #method2 moves first
            A1_move = alphabeta(n=root,
                                a=-INF,
                                b=INF,
                                d=depth2,
                                method=method,
                                depth=depth2,
                                my_color=A1_color,
                                opp_color=A2_color)
        Game.place(coordinates=A1_move.location, color=A1_color)
        if Game.is_game_over():
            if print_all:
                Game.print()
            if first == True:
                #if idtt win, return True
                return Game.check_win(A1_color)
            else:
                #if idtt win, return True
                return Game.check_win(A2_color)
        else:
            root = Tree(Game,
                        color=A1_color,
                        parent=None,
                        coordinate=A1_move.location,
                        my_color=A2_color)
            n_nodes = 0
            cutoff = 0
            flag = 0
            if first == True:
                A2_move = alphabeta(n=root,
                                    a=-INF,
                                    b=INF,
                                    d=depth2,
                                    method=method,
                                    depth=depth2,
                                    my_color=A2_color,
                                    opp_color=A1_color)
            else:
                A2_move = iterativedeepening(n=root,
                                             a=-INF,
                                             b=INF,
                                             DEPTH_stop=idtt_depth,
                                             time_limit=time_limit,
                                             my_color=A2_color,
                                             opp_color=A1_color)
            Game.place(coordinates=A2_move.location, color=A2_move.color)
            root = Tree(Game,
                        color=A2_color,
                        parent=None,
                        coordinate=A2_move.location,
                        my_color=A1_color)
    if print_all:
        Game.print()

    if first == True:
        #if method1 win or not
        return Game.check_win(A1_color)
    else:
        return Game.check_win(A2_color)
Exemplo n.º 9
0
def alphabeta_randomVSdijkstra(method1='random',
                               method2='dijkstra',
                               depth1=3,
                               depth2=3,
                               size=3,
                               print_all=False,
                               first=True):
    #alphabeta: method1 and method2 can choose 'random' or 'dijkstra'
    #first==True: method1 moves first
    #first determins which moves first
    global flag, user_color, unuse_color, INF, n_nodes, cutoff
    Game = HexBoard(size)
    #firt move color=A1_color: blue
    A1_color = 1
    #second move color=A1_color: red
    A2_color = 2
    root = Tree(Game,
                color=A2_color,
                parent=None,
                coordinate=None,
                my_color=A1_color)
    if print_all:
        if first == True:
            print('First move (blue) is ' + method1)
            print('Second move (red) is ' + method2)
        else:
            print('First move (blue) is ' + method2)
            print('Second move (red) is ' + method1)

    while not Game.is_game_over():
        INF = 99999
        flag = 0
        n_nodes = 0
        cutoff = 0
        if first == True:
            #method1 moves first
            A1_move = alphabeta(n=root,
                                a=-INF,
                                b=INF,
                                d=depth1,
                                method=method1,
                                depth=depth1,
                                my_color=A1_color,
                                opp_color=A2_color)
        else:
            #method2 moves first
            A1_move = alphabeta(n=root,
                                a=-INF,
                                b=INF,
                                d=depth2,
                                method=method2,
                                depth=depth2,
                                my_color=A1_color,
                                opp_color=A2_color)
        Game.place(coordinates=A1_move.location, color=A1_color)
        if Game.is_game_over():
            if print_all:
                Game.print()
            if first == True:
                #if method1 win, return True
                return Game.check_win(A1_color)
            else:
                #if method1 win, return True
                return Game.check_win(A2_color)
        else:
            root = Tree(Game,
                        color=A1_color,
                        parent=None,
                        coordinate=A1_move.location,
                        my_color=A2_color)
            n_nodes = 0
            cutoff = 0
            flag = 0
            if first == True:
                A2_move = alphabeta(n=root,
                                    a=-INF,
                                    b=INF,
                                    d=depth2,
                                    method=method2,
                                    depth=depth2,
                                    my_color=A2_color,
                                    opp_color=A1_color)
            else:
                A2_move = alphabeta(n=root,
                                    a=-INF,
                                    b=INF,
                                    d=depth1,
                                    method=method1,
                                    depth=depth1,
                                    my_color=A2_color,
                                    opp_color=A1_color)
            Game.place(coordinates=A2_move.location, color=A2_move.color)
            root = Tree(Game,
                        color=A2_color,
                        parent=None,
                        coordinate=A2_move.location,
                        my_color=A1_color)
    if print_all:
        Game.print()

    if first == True:
        #if method1 win or not
        return Game.check_win(A1_color)
    else:
        return Game.check_win(A2_color)