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

Python井字棋Minimax算法无法选择最优落子问题排查求助

你的Minimax算法问题排查与修复

我仔细看了你的井字棋代码,发现几个关键问题导致Bot无法选出最优解,尤其是你说的无法阻止你走1-5-9获胜的情况。咱们一步步来解决:

核心问题1:平局判断完全错误

你的checkdraw函数逻辑搞反了!当前它是当有玩家获胜时返回True,但平局的定义是「棋盘已满且没有任何人获胜」。这个错误会导致Minimax算法在平局时无法正确返回0分,进而让评分逻辑混乱,Bot无法做出正确的决策。

修复后的checkdraw应该是这样:

def checkdraw(board):
    # 先检查有没有人赢,有赢的就不是平局
    if checkForWin2():
        return False
    # 再检查棋盘是否还有空位
    for key in board.keys():
        if board[key] == ' ':
            return False
    # 没人赢且棋盘满了,就是平局
    return True

核心问题2:Minimax里多余的打印干扰(非逻辑错误但影响调试)

在minimax函数的最大化玩家分支里,你加了一个printboard(),这会在递归过程中疯狂打印棋盘,不仅看不清正常输出,还会拖慢算法。把这行删掉就行。

次要问题:冗余参数导致混淆

botgo函数的possibles参数完全没被用到(函数里直接遍历了board.keys()),可以删掉这个参数,让代码更清晰:

def botgo(mark):  # 移除possibles参数
    bestscore = -800
    bestmove = 0
    for key in board.keys():
        if (board[key] == ' '):
            board[key] = mark
            score = minimax(board,0,False)
            board[key] = ' '
            if(score > bestscore):
                bestscore = score
                bestmove = key
    insert(bestmove,mark='O')
    return

同时记得修改start函数里的调用:botgo(mark='O')

修复后的完整代码

board = {1: ' ', 2: ' ', 3: ' ', 4: ' ', 5: ' ', 6: ' ', 7: ' ', 8: ' ', 9: ' '}
win = False
turn = 1
depth = 1
nodeindex = 0
possibles= []
moves = []
depth = 0
targetdepth = 3
movesdone = []

def checkForWin(mark):
    if board[1] == board[2] == board[3] == mark:
        return True
    elif board[4] == board[5] == board[6] == mark:
        return True
    elif board[7] == board[8] == board[9] == mark:
        return True
    elif board[1] == board[4] == board[7] == mark:
        return True
    elif board[2] == board[5] == board[8] == mark:
        return True
    elif board[3] == board[6] == board[9] == mark:
        return True
    elif board[1] == board[5] == board[9] == mark:
        return True
    elif board[7] == board[5] == board[3] == mark:
        return True
    else:
        return False

def checkForWin2():
    if board[1] == board[2] == board[3] != ' ':
        return True
    elif board[4] == board[5] == board[6] != ' ':
        return True
    elif board[7] == board[8] == board[9] != ' ':
        return True
    elif board[1] == board[4] == board[7] != ' ':
        return True
    elif board[2] == board[5] == board[8] != ' ':
        return True
    elif board[3] == board[6] == board[9] != ' ':
        return True
    elif board[1] == board[5] == board[9] != ' ':
        return True
    elif board[7] == board[5] == board[3] != ' ':
        return True
    else:
        return False

def possiblemoves(board):
    possibles.clear()
    for i in board:
        if board[i] == " ":
            possibles.append(i)
    return possibles

def botgo(mark):
    bestscore = -800
    bestmove = 0
    for key in board.keys():
        if board[key] == ' ':
            board[key] = mark
            score = minimax(board, 0, False)
            board[key] = ' '
            if score > bestscore:
                bestscore = score
                bestmove = key
    insert(bestmove, mark='O')
    return

def printboard():
    print(board[1] + '|' + board[2] + '|' + board[3])
    print('-----')
    print(board[4] + '|' + board[5] + '|' + board[6])
    print('-----')
    print(board[7] + '|' + board[8] + '|' + board[9])

def start():
    turn = 1
    count = 0
    while count != 9:
        humango()
        printboard()
        possiblemoves(board)
        botgo(mark='O')
        printboard()
        count += 1

def spacefree(space):
    return board[space] == ' '

def insert(space, mark):
    if spacefree(space):
        board[space] = mark
        if checkForWin(mark):
            printboard()
            print("human win" if mark == 'X' else "BOT WIN")
            exit()
    else:
        print("cannot insert there!!!")
        space = int(input("Enter position"))
        insert(space, mark)

def checkdraw(board):
    if checkForWin2():
        return False
    for key in board.keys():
        if board[key] == ' ':
            return False
    return True

def humango():
    global turn
    space = int(input("Enter position"))
    insert(space, mark='X')
    turn += 1
    printboard()

def minimax(board, depth, ismax):
    if checkForWin(mark='O'):
        return 1
    elif checkForWin(mark='X'):
        return -1
    elif checkdraw(board):
        return 0
    if ismax:
        bestscore = -800
        for key in board.keys():
            if board[key] == ' ':
                board[key] = 'O'
                score = minimax(board, depth + 1, False)
                board[key] = ' '
                if score > bestscore:
                    bestscore = score
        return bestscore
    else:
        bestscore = 800
        for key in board.keys():
            if board[key] == ' ':
                board[key] = 'X'
                score = minimax(board, depth + 1, True)
                board[key] = ' '
                if score < bestscore:
                    bestscore = score
        return bestscore

start()

额外优化建议

  • 我简化了一些条件判断(比如board[1] == board[2] and board[1] == board[3]改成board[1] == board[2] == board[3]),让代码更简洁。
  • spacefree函数可以直接返回表达式,不用if-else,更简洁。
  • 全局变量太多了,比如possibles、depth这些其实很多没用到,可以考虑重构,把需要的变量作为参数传递,避免全局变量带来的潜在问题。

现在你再测试一下,Bot应该能正确阻止你走1-5-9的获胜路线了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:57:28