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

Minimax算法在Connect Four胜负场景识别中的异常问题求助

四子棋Minimax算法胜负评估问题排查建议

问题背景

这是一套用于四子棋(Connect Four)的Python版Minimax算法,由computer_move函数调用,用于计算棋盘可行步的估值。

预期行为

  • minimax函数根据棋盘状态和当前玩家返回局面估值:
    • 玩家1执行时,返回最高估值的步值;
    • 玩家2执行时,返回最低估值的步值。
  • computer_move函数调用minimax获取所有可行步的估值,从中选择最优步执行。

实际问题

computer_move能正确从minimax返回值中选择最优步,但minimax的估值逻辑存在核心问题:无法正确识别即时胜负或需要阻止对手胜负的场景。静态评估函数尚未实现,中间场景的行为未知,但在双方即将即时胜负的场景下,算法完全无法做出正确响应。

已尝试调整估值符号、交换max/min逻辑,但问题仍未解决;通过打印语句确认computer_move对返回值的处理逻辑正确,问题根源在minimax算法本身,但目前认为代码符合标准Minimax实现,需要明确排查方向。


相关代码

Minimax函数实现

import math

def minimax(board, depth, alpha, beta, player, move):
    # 基准情况
    if check_winning(board, 1) or check_winning(board, 2):
        player = player*2-3     # 转换为 +/-1
        return player*math.inf
    elif depth==0:
        return static_eval(board)

    # 玩家1寻找最高估值的走法
    if player==1:
        max_eval = -math.inf
        for move in range(COLUMNS):
            if valid_move(board, move):
                make_move(board, move, player)
                eval = minimax(board, depth-1, alpha, beta, 2, move)
                unmake_move(board, move)
                max_eval = max(max_eval, eval)
                alpha = max(alpha, eval)
                if beta <= alpha:
                    break
        return max_eval

    # 玩家2寻找对玩家1来说最低估值的走法
    else:
        min_eval = math.inf
        for move in range(COLUMNS):
            if valid_move(board, move):
                make_move(board, move, player)
                #print_board(board)
                eval = minimax(board, depth-1, alpha, beta, 1, move)
                unmake_move(board, move)
                min_eval = min(min_eval, eval)
                beta = min(beta, eval)
                if beta <= alpha:
                    break
        return min_eval

调用Minimax并执行最优步的代码

# 获取所有走法的估值列表,根据玩家选择最高/最低估值的走法
def computer_move(board, player, difficulty=3):
    move_vals=[]
    for move in range(COLUMNS):
        if(valid_move(board, move)):
            move_vals.append(minimax(board,
                                     difficulty, 
                                     -math.inf, 
                                     math.inf, 
                                     player, 
                                     move))
        else:
            move_vals.append(-math.inf)

    min_val = min(move_vals)
    max_val = max(move_vals)
    if(player==1):
        move = move_vals.index(max_val)
    else:
        move = move_vals.index(min_val)

    make_move(board, move, player)

    print('Here is the computer\'s move:')
    print_board(board)

排查建议

  1. 修正胜负判断的基准逻辑
    当前基准条件中,只要检测到任意玩家获胜就返回player*math.inf,但这里的player是当前要走棋的玩家,而非刚刚获胜的玩家。例如:玩家1走完一步触发胜利后,递归回到上一层时当前player是玩家2,此时返回值为+inf,但这对玩家2来说是失败局面,应返回-inf才符合估值逻辑。
    修正方案:直接判断获胜玩家,返回对应视角的估值——玩家1获胜返回+inf,玩家2获胜返回-inf(估值始终站在玩家1的视角)。

  2. 验证胜负检测函数的正确性
    单独测试check_winning函数,传入明确的胜利局面(比如玩家1在某列/行/对角线连成四子),确认函数能正确返回对应玩家的胜利状态,避免因检测逻辑错误导致基准条件触发异常。

  3. 删除冗余参数
    minimax函数的move参数在内部被循环变量覆盖,完全未发挥作用,属于冗余参数,建议删除,避免混淆逻辑。

  4. 确认递归视角一致性
    Minimax的估值需始终站在同一视角(如玩家1的视角):玩家1要最大化估值,玩家2要最小化估值。检查递归过程中估值的传递逻辑,确保每一层的max/min选择都符合当前玩家的目标。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:01:01