我在尝试实现一个极小化-极大化算法来创建一个井字游戏机器人,但遇到了RecursionError: maximum recursion depth exceeded in comparison错误。我的代码如下。我已经添加了注释,说明每个函数的作用。你能看一下下面的代码吗?谢谢
X = "X"O = "O"EMPTY = Nonedef initial_state(): """ 返回棋盘的初始状态。 """ return [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]]def player(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): """ 返回棋盘上所有可能的动作(i, j)。 """ action = [] for i in range(3): for j in range(3): if board[i][j] is None: action.append([i, j]) return actiondef result(board, action): """ 返回在棋盘上执行动作(i, j)后的结果棋盘。 """ p = player(board) i, j = action board[i][j] = p return boarddef winner(board): """ 返回游戏的赢家,如果有的话。 """ 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): """ 如果游戏结束,返回True,否则返回False。 """ 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 Falsedef utility(board): """ 如果X赢了游戏,返回1;如果O赢了,返回-1;否则返回0。 """ if winner(board) == 'X': return 1 elif winner(board) == 'O': return -1 else: return 0def 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 vdef 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 vdef minimax(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
回答:
你的问题是陷入了无限循环,这意味着你会一直递归调用函数直到达到递归限制。你的问题出在你的player函数以及你如何决定下一个该谁走。当O在位置0,0下棋,X在位置0,1下棋后,你试图决定下一个该谁走
所以你计算了O和X各放置了一个棋子。然而,你决定下一个该谁走的逻辑并没有考虑到这种棋盘状态。
if x_counter == 0 and o_counter == 0: return 'O' elif x_counter > o_counter: return 'O' elif o_counter > x_counter: return 'X'
所以当x_counter和y_counter相等但不为0时,你没有返回任何值。这导致函数返回None,所以你卡住了,永远不会在位置0,2放置棋子。如果O总是先走,那么每当x_counter == o_counter时,你应该返回'O',所以将其改为
if x_counter == o_counter: return 'O' elif x_counter > o_counter: return 'O' elif o_counter > x_counter: return 'X'