Python实现Tic Tac Toe(井字棋)AI不败的高效逻辑优化问询
井字棋AI落子逻辑优化方案
核心优化思路
你现在的代码冗余根源是硬编码了所有获胜组合的判断逻辑,只要把所有获胜线抽成公共常量,再统一遍历判断,就能砍掉所有重复的if/elif代码。如果要实现100%不败,直接用极小极大算法穷举所有游戏状态即可,井字棋总状态数只有不到30万,计算开销可以忽略。
第一步:抽取公共获胜线常量
首先把所有8种获胜组合定义为全局常量,胜负检测、落子判断都复用这个常量:
# 所有获胜的三个格子坐标组合 WIN_LINES = [ [(0,0), (0,1), (0,2)], [(1,0), (1,1), (1,2)], [(2,0), (2,1), (2,2)], # 行 [(0,0), (1,0), (2,0)], [(0,1), (1,1), (2,1)], [(0,2), (1,2), (2,2)], # 列 [(0,0), (1,1), (2,2)], [(0,2), (1,1), (2,0)] # 对角线 ]
对应你的胜负检测逻辑可以简化为:
def check(board, player): for line in WIN_LINES: if all(board[x][y] == player for x,y in line): win.player_won(player) return
第二步:极简拦截+优先赢落子逻辑
不需要写任何硬编码的if判断,直接遍历获胜线即可,落子按以下优先级:
- 优先走能让自己直接赢的位置
- 其次走拦截对手赢的位置
- 剩下的位置按中心>角>边的优先级选择
代码示例:
def ai_move(board): # 优先级1:检查自己能不能直接赢 for line in WIN_LINES: positions = [board[x][y] for x,y in line] if positions.count('X') == 2 and positions.count('#') == 1: # 找到空位置落子 for x,y in line: if board[x][y] == '#': board[x][y] = 'X' return # 优先级2:拦截对手的获胜位置 for line in WIN_LINES: positions = [board[x][y] for x,y in line] if positions.count('O') == 2 and positions.count('#') == 1: for x,y in line: if board[x][y] == '#': board[x][y] = 'X' return # 优先级3:占中心 if board[1][1] == '#': board[1][1] = 'X' return # 优先级4:占四个角 corners = [(0,0), (0,2), (2,0), (2,2)] for x,y in corners: if board[x][y] == '#': board[x][y] = 'X' return # 优先级5:占剩下的边位 edges = [(0,1), (1,0), (1,2), (2,1)] for x,y in edges: if board[x][y] == '#': board[x][y] = 'X' return
这个版本已经可以做到几乎不会输,代码量比你原来的硬编码if少80%以上,可维护性极高。
第三步:100%不败的极小极大实现
如果要保证绝对不会输,可以用极小极大算法穷举所有可能的落子路径,计算每个位置的最优得分:
def minimax(board, depth, is_maximizing): # 终止状态判断:X赢返回1,O赢返回-1,平局返回0 for line in WIN_LINES: vals = [board[x][y] for x,y in line] if vals == ['X','X','X']: return 1 if vals == ['O','O','O']: return -1 # 棋盘满了平局 if all(board[x][y] != '#' for x in range(3) for y in range(3)): return 0 if is_maximizing: best_score = -float('inf') for x in range(3): for y in range(3): if board[x][y] == '#': board[x][y] = 'X' score = minimax(board, depth+1, False) board[x][y] = '#' best_score = max(score, best_score) return best_score else: best_score = float('inf') for x in range(3): for y in range(3): if board[x][y] == '#': board[x][y] = 'O' score = minimax(board, depth+1, True) board[x][y] = '#' best_score = min(score, best_score) return best_score # AI落子调用 def best_ai_move(board): best_score = -float('inf') best_pos = None for x in range(3): for y in range(3): if board[x][y] == '#': board[x][y] = 'X' score = minimax(board, 0, False) board[x][y] = '#' if score > best_score: best_score = score best_pos = (x,y) board[best_pos[0]][best_pos[1]] = 'X'
这个版本可以保证AI要么赢要么平局,绝对不会输。
内容的提问来源于stack exchange,提问作者J3B
相关产品推荐
相关产品推荐

