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

Python井字棋Minimax算法输出错误,请求问题排查

井字棋Minimax算法错误排查

我正在实现井字棋的Minimax算法,但部分场景下算法会输出明显错误的走法。比如当前棋盘状态(轮到X落子):

X . .
. O .
. . .

最优走法应该是底部角落,但算法却输出顶部中间位置。我找不到算法正确和错误的规律,怀疑是语法错误或者整体思路有问题。我是编程新手,核心代码如下:

def moveSearch(board, player) :
    #printBoard(board)
    if abs(checkWin(board)) == 1 :
        return checkWin(board) * player * -1
    elif checkWin(board) == 0: 
        return 0
    elif checkWin(board) == 2 :
        moveList = array('i', [])
        i = 0
        while i < 9 :
            if board[i] == 0 :
                moveList.append(i)
            i += 1
        j = 0
        valueList = array('f', [0] * len(moveList))
        while j < len(moveList) :
            board[moveList[j]] = player
            valueList[j] = moveSearch(board, -1 * player)
            board[moveList[j]] = 0
            j += 1
        return max(valueList) * -1
 
def topLevelSearch(board, player) :
    printBoard(board)
    if abs(checkWin(board)) == 1 :
        return
    elif checkWin(board) == 0: 
        return
    elif checkWin(board) == 2 :
        moveList = array('i', [])
        i = 0
        while i < 9 :
            if board[i] == 0 :
                moveList.append(i)
            i += 1
        j = 0
        valueList = array('f', [0] * len(moveList))
        while j < len(moveList) :
            board[moveList[j]] = player
            valueList[j] = moveSearch(board, -1 * player)
            board[moveList[j]] = 0
            j += 1
        bestMove = moveList[valueList.index(max(valueList))]
        return bestMove

问题分析

你的核心问题出在Minimax的价值计算和递归逻辑颠倒,以及终止条件的价值判断混乱:

  1. 终止条件价值计算错误:checkWin(board)的返回值和后续乘法逻辑不匹配,导致获胜局面的价值被错误反转,算法无法识别最优走法。
  2. 递归逻辑不符合Minimax核心:不管当前是最大化玩家(X)还是最小化玩家(O),你都统一取子节点最大值再乘-1,完全颠倒了“最大化自己收益、最小化对手收益”的逻辑。
  3. 不必要的array类型:使用array('i')和array('f')增加了复杂度,普通列表完全可以满足需求,还能减少出错概率。

修正后的代码

首先明确checkWin的返回值定义:

  • 返回1:X获胜
  • 返回-1:O获胜
  • 返回0:平局
  • 返回2:游戏未结束

修正后的核心代码:

def moveSearch(board, player):
    result = checkWin(board)
    # 终止条件:返回当前局面的价值
    if result == 1:
        return 1  # X赢,对X来说是正收益
    elif result == -1:
        return -1  # O赢,对X来说是负收益
    elif result == 0:
        return 0  # 平局无收益
    
    # 生成所有空位置的走法
    move_list = [i for i in range(9) if board[i] == 0]
    
    if player == 1:  # 当前是X,最大化玩家:选收益最高的走法
        max_val = -float('inf')
        for move in move_list:
            board[move] = player
            current_val = moveSearch(board, -1)
            board[move] = 0  # 回溯
            if current_val > max_val:
                max_val = current_val
        return max_val
    else:  # 当前是O,最小化玩家:选让X收益最低的走法
        min_val = float('inf')
        for move in move_list:
            board[move] = player
            current_val = moveSearch(board, 1)
            board[move] = 0  # 回溯
            if current_val < min_val:
                min_val = current_val
        return min_val

def topLevelSearch(board, player):
    printBoard(board)
    result = checkWin(board)
    if result in (1, -1, 0):
        return
    
    move_list = [i for i in range(9) if board[i] == 0]
    best_val = -float('inf')
    best_move = None
    
    for move in move_list:
        board[move] = player
        current_val = moveSearch(board, -1)  # 调用对手视角的搜索
        board[move] = 0
        if current_val > best_val:
            best_val = current_val
            best_move = move
    return best_move

关键修正点说明

  1. 明确价值逻辑:终止条件直接返回局面的真实价值,X赢得正分,O赢得负分,平局0分,算法能清晰判断优劣。
  2. 区分玩家类型:最大化玩家(X)取子节点的最大值,最小化玩家(O)取子节点的最小值,完全符合Minimax的核心思想。
  3. 简化代码结构:用列表推导式生成走法,替换繁琐的while循环,减少语法错误概率。
  4. 严谨跟踪最佳走法:直接遍历比较价值,避免index(max())可能出现的多值冲突问题(比如多个走法价值相同时,取第一个遇到的最优解)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:00:53