井字棋游戏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 | ____|___|____ | | | | ____|___|____ | | | | | |
错误修正说明
- 修复Minimax平局判断:将
elif not board_full:改为elif not board_full(),正确调用函数判断棋盘是否已满,否则永远不会触发平局逻辑。 - 修正AI的Minimax调用角色:AI作为最大化玩家,调用
minimax时传入ismax=True,确保算法以正确的身份评估得分。 - 修复AI落子的位置检查:将
if position_check:改为if board[b] == ' ',直接验证目标位置是否为空,避免依赖外部变量的错误逻辑。 - 初始化最佳位置变量:在AI遍历位置前添加
bestmove = 0,防止因所有位置得分相同导致变量未赋值的错误。 - 移除无效的depth依赖:如果完全不想使用深度概念,可将Minimax函数的
depth参数及递归调用中的depth+1移除,当前代码中depth未影响逻辑,可直接删除。
内容的提问来源于stack exchange,提问作者Harsh Mishra
相关产品推荐
相关产品推荐

