简体   繁体   English

我正在尝试实现一个极小极大算法来创建一个井字游戏机器人,但我遇到了递归错误

[英]I'm trying to implement a minimax algorithm to create a tic-tac-toe bot, but i'm getting a recursion error

I'm trying to implement a minimax algorithm to create a tic-tac-toe bot, but i'm getting RecursionError: maximum recursion depth exceeded in comparison error.我正在尝试实现一个极小极大算法来创建一个井字游戏机器人,但我得到了 RecursionError: maximum recursion depth exceeded in comparison 错误。 I have the code below.我有下面的代码。 I've added comments that mention what a function is supposed to do.我添加了提到 function 应该做什么的评论。 I last Can you take a look at the code below.我最后你能不能看一下下面的代码。 Thank you谢谢

X = "X"
O = "O"
EMPTY = None

def initial_state():
    """
    Returns starting state of the board.
    """
    return [[EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY]]


def player(board):
    """
    Returns player who has the next turn on a board.
    """
    o_counter = 0
    x_counter = 0
    for i in board:
        for j in i:
            if j == 'X':
                x_counter += 1
            elif j == 'O':
                o_counter += 1
    if x_counter == 0 and o_counter == 0:
        return 'O'
    elif x_counter > o_counter:
        return 'O'
    elif o_counter > x_counter:
        return 'X'



def actions(board):
    """
    Returns set of all possible actions (i, j) available on the board.
    """
    action = []
    for i in range(3):
        for j in range(3):
            if board[i][j] is None:
                action.append([i, j])
    return action


def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    p = player(board)
    i, j = action
    board[i][j] = p
    return board


def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    i = 1
    if board[0][0] == board[1][1] == board[2][2] and (board[0][0] == 'X' or board[0][0] == 'O'):
        return board[0][0]
    elif board[0][2] == board[1][1] == board[2][0] and (board[0][2] == 'X' or board[0][2] == 'O'):
        return  board[0][2]
    else:
        if board[0][0] == board[0][1] == board[0][2] and (board[0][0] == 'X' or board[0][0] == 'O'):
            return board[0][0]
        elif board[i][0] == board[i][1] == board[i][2] and (board[i][0] == 'X' or board[i][0] == 'O'):
            return board[i][0]
        elif board[2][0] == board[2][1] == board[2][2] and (board[2][0] == 'X' or board[2][0] == 'O'):
            return board[2][0]

        elif board[0][0] == board[1][0] == board[2][0] and (board[0][0] == 'X' or board[0][0] == 'O'):
            return board[0][0]
        elif board[0][i] == board[1][i] == board[2][i] and (board[0][i] == 'X' or board[0][i] == 'O'):
            return board[0][i]
        elif board[0][2] == board[1][2] == board[2][2] and (board[0][2] == 'X' or board[0][2] == 'O'):
            return board[0][2]

def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    check = True
    if winner(board) == 'X' or winner(board) == 'O':
        return True
    elif check:
        for i in board:
            for j in i:
                if j is None:
                    check = False
                    return False
        if check:
            return True
    else:
        return False


def utility(board):
    """
    Returns 1 if X has won the game, -1 if O has won, 0 otherwise.
    """
    if winner(board) == 'X':
        return 1
    elif winner(board) == 'O':
        return -1
    else:
        return 0


def maximum(board):
    if terminal(board):
        return utility(board)
    v = -9999999999999999999999
    for action in actions(board):
        m = minimum(result(board, action))
        if m > v:
            v = m
    return v


def minimum(board):
    if terminal(board):
        return utility(board)
    v = 9999999999999999999999
    for action in actions(board):
        m = maximum(result(board, action))
        if m < v:
            v = m
    return v


def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """
    return_action = None
    curr_player = player(board)
    states = actions(board)
    temp_board = board.copy()
    score = 0
    temp_score = 0
    for state in states:
        i, j = state
        if curr_player == 'X':
            temp_board[i][j] = curr_player
            temp_score = maximum(temp_board)
        elif curr_player == 'O':
            temp_board[i][j] = curr_player
            temp_score = minimum(temp_board)
        if curr_player == 'X':
            if temp_score > score:
                score = temp_score
                return_action = state
        elif curr_player == 'O':
            if temp_score < score:
                score = temp_score
                return_action = state

    return  return_action

Your issue is your stuck in an infinite condition which means you keep recursively calling the function till you reach the recursion limit.您的问题是您陷入无限状态,这意味着您不断递归调用 function 直到达到递归限制。 Your issue comes in your player function and how you decide whos turn is next.您的问题在于您的玩家 function 以及您如何决定下一个轮到谁。 After O plays in position 0,0 and X plays in position 0,1 you then try to decide who is next to play在 O 播放 position 0,0 和 X 播放 position 0,1 之后,您然后尝试决定谁是下一个播放

So you count and both O and X have placed 1 token each.所以你数了数,O 和 X 都各放置了 1 个令牌。 However your logic to decide who is next doesnt cater for this board state.但是,您决定下一个是谁的逻辑不适合此板 state。

    if x_counter == 0 and o_counter == 0:
        return 'O'
    elif x_counter > o_counter:
        return 'O'
    elif o_counter > x_counter:
        return 'X'

so when x_counter and y_counter are equal but are not 0 you dont return anything.因此,当 x_counter 和 y_counter 相等但不为 0 时,您不会返回任何内容。 This results in None being returned by the function So your stuck and never then place a token in position 0,2.这导致 function 返回 None 所以你卡住了,然后永远不要在 position 0,2 中放置令牌。 If O always goes first then any time x_counter == o_counter you should return '0' so change it to如果 O 总是先走,那么任何时候 x_counter == o_counter 你应该返回 '0' 所以把它改成

    if x_counter == o_counter:
        return 'O'
    elif x_counter > o_counter:
        return 'O'
    elif o_counter > x_counter:
        return 'X'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM