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

井字棋游戏Minimax算法失效,AI走非最优步问题求助

井字棋Minimax算法错误排查

我近期学习了Minimax算法,尝试实现一款不可击败的井字棋AI,但Minimax函数无法正常工作,AI有时会走出非最优步骤。例如当我选择位置1落子时,AI本应走中心位置5,却总是走位置2,最终导致失败。我不想使用深度相关的概念,以下是完整代码及运行示例:

原代码

from random import randint
import os

def play_again():
    print()
    t=True
    while t:
        p=input("Do you want to play again? Y or N  ").upper()
        if p=='Y' or p=='YES':
            t=False
            return True
        elif p=='N' or p=='NO':
            t=False
            print("Thank You!!")
            return False
        else:
            print('Enter a valid input!')
            
    
        
while True:

    board1=['1','2','3','4','5','6','7','8','9']
    print('    |   |')
    print(' ',board1[0],'|',board1[1],'|',board1[2])
    print('____|___|____')
    print('    |   |')
    print(' ',board1[3],'|',board1[4],'|',board1[5])
    print('____|___|____')
    print('    |   |')
    print(' ',board1[6],'|',board1[7],'|',board1[8])
    print('    |   |')

    
    board=[' ',' ',' ',' ',' ',' ',' ',' ',' ']
    def print_board():
        
        print('    |   |')
        print(' ',board[0],'|',board[1],'|',board[2])
        print('____|___|____')
        print('    |   |')
        print(' ',board[3],'|',board[4],'|',board[5])
        print('____|___|____')
        print('    |   |')
        print(' ',board[6],'|',board[7],'|',board[8])
        print('    |   |')


    if randint(0,1)==0:
        player='Player 1'
    else:
        player='Player 2'


    a='a'
    while a not in ['X','O']:
        a=input("Player 1: Do you want to be X or O: ").upper()
            
        if a not in ['X','O']:
            print("Enter valid output X or O")

    if a=='X':
        c='O'
    else:
        c='X'

    def first():
        if player=='Player 1':
            print()
            print('Player 1 will go first')
            
        else:
            print()
            print('Player 2 will go first')
            
    first()

    def position_check():
        return board[b-1] not in ['X','O']

    def board_full():
        for i in board:
            if i not in ['X','O']:
                return True
        return False


    def win_check(m):
        return ((board[0]==m and board[1]==m and board[2]==m) or
                (board[3]==m and board[4]==m and board[5]==m) or
                (board[6]==m and board[7]==m and board[8]==m) or
                (board[0]==m and board[3]==m and board[6]==m) or
                (board[1]==m and board[4]==m and board[7]==m) or
                (board[2]==m and board[5]==m and board[8]==m) or
                (board[0]==m and board[4]==m and board[8]==m) or
                (board[2]==m and board[4]==m and board[6]==m))

    def minimax(board,depth,ismax):
        
        if win_check(c):
            return 1

        elif win_check(a):
            return -1

        elif not board_full:
            return 0

        if ismax:
            bestscore = -1000

            for i in range(len(board)):
                
                if board[i]==' ':
                    board[i]=c
                    score= minimax(board,depth+1,False)
                    
                    board[i]=' '

                    if score > bestscore:
                        bestscore = score

            return bestscore

        else:
            bestscore = 1000

            for i in range(len(board)):
                if board[i]==' ':
                    
                    board[i]=a

                    score= minimax(board,depth+1,True)
                    
                    board[i]=' '

                    if score < bestscore:
                        bestscore = score

            return bestscore
            
        
    while board_full():
        
        if player=='Player 1':
            b='a'
            within_range=False
            while b.isdigit()==False or within_range==False:
                b=input("Enter your next move (1-9) :")

                if b.isdigit()==False:
                    print('\n'*100)
                    print('Enter a choice between 1-9')

                if b.isdigit()==True:
                    if int(b) in range(1,10):
                        within_range=True
                    else:
                        print('Enter a choice between 1-9')

            b=int(b)

            if position_check():
                board[b-1]=a
                print_board()
                if win_check(a):
                    print('Congratulations Player 1 wins!!')
                    break
                else:
                    player='Player 2'

            else:
                print('Position already occupied')

        if player=='Player 2':

            bestscore = -1000

            for i in range(len(board)):
                if board[i]==' ':
                    board[i]=c

                    score= minimax(board,0,False)
                    
                    board[i]=' '

                    if score > bestscore:
                        bestscore = score
                        bestmove=i
                        b=bestmove

            if position_check:
                
                board[b]=c
                
                print_board()
                
                if win_check(c):
                    print('Congratulations Player 2 wins!!')
                    break
                else:
                    player='Player 1'
                    
                


    else:
        print('Its a DRAW!!')


    if not play_again():
        break

运行示例

|   |
  1 | 2 | 3
____|___|____
    |   |
  4 | 5 | 6
____|___|____
    |   |
  7 | 8 | 9
    |   |
Player 1: Do you want to be X or O: x

Player 1 will go first
Enter your next move (1-9) :1
    |   |
  X |   |  
____|___|____
    |   |
    |   |  
____|___|____
    |   |
    |   |  
    |   |
    |   |
  X | O |  
____|___|____
    |   |
    |   |  
____|___|____
    |   |
    |   |  
    |   |

错误修正说明

  1. 修复Minimax平局判断:将elif not board_full:改为elif not board_full(),正确调用函数判断棋盘是否已满,否则永远不会触发平局逻辑。
  2. 修正AI的Minimax调用角色:AI作为最大化玩家,调用minimax时传入ismax=True,确保算法以正确的身份评估得分。
  3. 修复AI落子的位置检查:将if position_check:改为if board[b] == ' ',直接验证目标位置是否为空,避免依赖外部变量的错误逻辑。
  4. 初始化最佳位置变量:在AI遍历位置前添加bestmove = 0,防止因所有位置得分相同导致变量未赋值的错误。
  5. 移除无效的depth依赖:如果完全不想使用深度概念,可将Minimax函数的depth参数及递归调用中的depth+1移除,当前代码中depth未影响逻辑,可直接删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:09:52