Python井字棋result函数报'int'不可下标错误求助
井字棋
result函数调用触发TypeError错误 错误回溯信息
board = ttt.result(board, move) File "c:\Users\ACER\Desktop\Projects\artificial intelligence with python\tictactoe\tictactoe\tictactoe.py", line 66, in result cell = new_board[action[0]][action[1]] TypeError: 'int' object is not subscriptable
tictactoe.py核心代码
X="X" O="O" EMPTY= None initial_board = [[EMPTY,EMPTY,EMPTY],[EMPTY,EMPTY,EMPTY],[EMPTY,EMPTY,EMPTY]] def result(board, action): """ Returns the board that results from making move (i, j) on the board. """ memo = {} new_board = copy.deepcopy(board, memo) # 引发异常的代码行 cell = new_board[action[0]][action[1]] move = player(board) if cell is not EMPTY: raise Exception("That move is not allowed") else: new_board[action[0]][action[1]] = move return new_board
GUI调用代码(runner.py)
# 检查AI落子 if user != player and not game_over: if ai_turn: time.sleep(0.5) move = ttt.minimax(board) board = ttt.result(board, move) ai_turn = False else: ai_turn = True # 检查用户落子 click, _, _ = pygame.mouse.get_pressed() if click == 1 and user == player and not game_over: mouse = pygame.mouse.get_pos() for i in range(3): for j in range(3): if (board[i][j] == ttt.EMPTY and tiles[i][j].collidepoint(mouse)): board = ttt.result(board, (i, j))
AI寻优相关代码
def max_value(board): """ Given the AI is "X"(Maximizer), returns the value of the utility if the terminal state has been reached, otherwise return the value of the utility that will result in optimal play. """ if terminal(board): return utility(board) else: v = -(math.inf) for action in actions(board): v = max(v, min_value(result(board, action))) return v def min_value(board): """ Given the AI is "O"(Minimizer), returns the value of the utility if the terminal state has been reached, otherwise return the value of the utility that will result in optimal play. """ if terminal(board): return utility(board) else: v = math.inf for action in actions(board): v = min(v, max_value(result(board, action))) return v def minimax(board): """ Returns the optimal action for the current player on the board. """ if player(board) == X: return max_value(board) elif player(board) == O: return min_value(board)
辅助函数说明:
player(board):返回下一回合的玩家(X或O)terminal(board):游戏结束返回True,否则返回Falseutility(board):X获胜返回1,O获胜返回-1,平局返回0
问题原因与解决方案
问题根源
minimax函数当前返回的是max_value或min_value的结果(整数类型的效用值:1、-1或0),但runner.py中把这个返回值当作二元组类型的action传给result函数,导致action被识别为整数,触发action[0]的下标访问错误。
修正方案
修改minimax函数,让它遍历所有可用动作,找到对应最优效用值的动作并返回:
import math def minimax(board): """ Returns the optimal action for the current player on the board. """ current_player = player(board) if current_player == X: best_value = -math.inf best_action = None for action in actions(board): # 计算执行该动作后的效用值 value = min_value(result(board, action)) if value > best_value: best_value = value best_action = action return best_action elif current_player == O: best_value = math.inf best_action = None for action in actions(board): value = max_value(result(board, action)) if value < best_value: best_value = value best_action = action return best_action
修改后,minimax会返回正确的二元组动作,传给result函数后就能正常执行下标访问,解决报错问题。
内容的提问来源于stack exchange,提问作者Tanatswa
相关产品推荐
相关产品推荐

