You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

井字棋AI运行报错:move not in the set,请求修复指导

Tic Tac Toe AI代码修复方案

问题重现

运行代码时触发以下错误:

Traceback (most recent call last):
File "C:\Users\Dell\Downloads\tictactoe\tictactoe\runner.py", line 116, in
board = ttt.result(board, move)
File "C:\Users\Dell\Downloads\tictactoe\tictactoe\tictactoe.py", line 66, in result
raise Exception("move not in the set ")
Exception: move not in the set

经排查,result函数接收到的action参数为None,根源在minimax函数的实现错误。

错误点分析

  1. minimax函数语法与逻辑错误:
    • append方法仅接受一个参数,原代码中拆分传入分数和行动的写法语法错误。
    • 遍历候选行动时使用range(len(score_play)-1)会遗漏最后一个元素,导致无法选中最优解。
    • O玩家分支中存在无意义的循环代码,可能引发类型错误。
  2. player函数分支缺失:
    • 当X和O步数相同时(初始状态或回合交替后),未返回先手玩家X,会导致返回None引发后续异常。
  3. terminal函数逻辑顺序错误:
    • 先检查棋盘空位再判断赢家,导致已分出胜负但棋盘未填满时,错误判定游戏未结束。

修复后的完整代码

"""
Tic Tac Toe Player
"""

import math
import copy
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.
    """
    countx = 0
    counto = 0
    for i in range(3):
        for j in range(3):
            if board[i][j] == X:
                countx += 1
            if board[i][j] == O:
                counto += 1

    # X先手,步数相同时X行动
    if countx == counto:
        return X
    elif countx > counto:
        return O
    else:
        return X


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


def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    current_player = player(board)
    new_all_actions = actions(board)
    if action not in new_all_actions:
        raise Exception("move not in the set ")
    i, j = action 
    copy_board = copy.deepcopy(board)
    copy_board[i][j] = current_player
    return copy_board


def check_row(board, player):
    for i in range(3):
        if board[i][0] == player and board[i][1] == player and board[i][2] == player:
            return True
    return False

def check_column(board, player):
    for i in range(3):
        if board[0][i] == player and board[1][i] == player and board[2][i] == player:
            return True
    return False

def check_diagonals(board, player):
    if board[0][0] == player and board[1][1] == player and board[2][2] == player:
        return True
    elif board[0][2] == player and board[1][1] == player and board[2][0] == player:
        return True
    return False

def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    if check_column(board, X) or check_row(board, X) or check_diagonals(board, X):
        return X
    elif check_column(board, O) or check_row(board, O) or check_diagonals(board, O):
        return O
    return None


def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    # 优先判断是否有赢家
    if winner(board) is not None:
        return True
    # 检查棋盘是否还有空位
    for i in range(3):
        for j in range(3):
            if board[i][j] == EMPTY:
                return False
    # 无赢家且棋盘满,游戏结束
    return True


def utility(board):
    """
    Returns 1 if X has won the game, -1 if O has won, 0 otherwise.
    """
    if not terminal(board):
        raise Exception("game not over")
    if winner(board) == X:
        return 1
    if winner(board) == O:
        return -1
    else:
        return 0

def max_value(board):
    v = -math.inf
    if terminal(board):
        return utility(board)
    for action in actions(board):
        v = max(v, min_value(result(board, action)))
    return v
        
def min_value(board):
    v = math.inf
    if terminal(board):
        return utility(board)
    for action in actions(board):
        v = min(v, max_value(result(board, action)))
    return v 

def minimax(board):
    if terminal(board):
        return None
    current_player = player(board)
    
    if current_player == X:
        max_variable = -math.inf
        best_action = None
        # 遍历所有可能行动,记录最优解
        for action in actions(board):
            current_score = min_value(result(board, action))
            if current_score > max_variable:
                max_variable = current_score
                best_action = action
        return best_action
    
    elif current_player == O:
        min_variable = math.inf
        best_action = None
        # 遍历所有可能行动,记录最优解
        for action in actions(board):
            current_score = max_value(result(board, action))
            if current_score < min_variable:
                min_variable = current_score
                best_action = action
        return best_action

修复说明

  • 重构minimax函数逻辑,直接遍历行动并实时记录最优解,避免语法错误与冗余操作。
  • 完善player函数的分支覆盖,确保所有场景下都能返回正确的当前玩家。
  • 调整terminal函数的判断顺序,优先判定是否有赢家,保证游戏结束状态的准确性。

内容的提问来源于stack exchange,提问作者Philip Sebastian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 19:05:06