Godot 4.0 井字棋Minimax AI故障求助:无法阻断获胜线路
井字棋Minimax AI问题修复方案
核心问题分析
你的AI出现不阻断玩家获胜路线的情况,主要源于两处关键逻辑错误:
1. Minimax递归调用的角色方向错误
在find_best_move函数中,模拟AI落子后,调用minimax时错误传入is_maximizing: true。此时AI已完成一步落子,接下来是人类玩家(最小化方)的回合,应传入false。该错误导致AI评分逻辑完全颠倒,无法正确评估后续局面。
2. 胜负评分的符号逻辑混乱
minimax函数的胜负判断分支中,(winner * (size - depth)) * (1 if depth % 2 == 0 else -1)的计算逻辑错误。假设PLAYER_O为AI(值1)、PLAYER_X为人类玩家(值-1),AI获胜应返回正高分,人类获胜应返回负低分,当前的奇偶翻转会让AI误将“自己输”的局面判为高分,进而选择错误落子。
修复后的代码
修正minimax函数的评分逻辑
var INFINITY = 10000000 var gridSize = 3 var game_depth = 50 var win_length = 3 #================================================================================================= func minimax(grid: Array, size: int, length: int, depth: int, alpha: int, beta: int, is_maximizing: bool) -> int: var winner = check_winner(grid, size, length) if winner != EMPTY: # AI获胜返回正分,人类获胜返回负分,depth越小分数越高(优先最快获胜/阻断) var score = size - depth return score if winner == PLAYER_O else -score if depth >= game_depth: return 0 if is_maximizing: var best_value = -INFINITY for r in range(size): for c in range(size): if grid[r * size + c] == EMPTY: grid[r * size + c] = PLAYER_O var value = minimax(grid, size, length, depth + 1, alpha, beta, false) grid[r * size + c] = EMPTY best_value = max(value, best_value) alpha = max(alpha, best_value) if beta <= alpha: break # 剪枝后同步跳出外层循环 if beta <= alpha: break return best_value else: var best_value = INFINITY for r in range(size): for c in range(size): if grid[r * size + c] == EMPTY: grid[r * size + c] = PLAYER_X var value = minimax(grid, size, length, depth + 1, alpha, beta, true) grid[r * size + c] = EMPTY best_value = min(value, best_value) beta = min(beta, best_value) if beta <= alpha: break # 剪枝后同步跳出外层循环 if beta <= alpha: break return best_value #================================================================================================= func find_best_move(grid: Array, size: int, length: int) -> Vector2: var best_value = -INFINITY var best_move = Vector2(-1, -1) for r in range(size): for c in range(size): if grid[r * size + c] == EMPTY: grid[r * size + c] = PLAYER_O # 模拟AI落子后轮到人类玩家(最小化方),is_maximizing传false var move_value = minimax(grid, size, length, 0, -INFINITY, INFINITY, false) grid[r * size + c] = EMPTY if move_value > best_value or (move_value == best_value and randf() > 0.5): best_value = move_value best_move = Vector2(c, r) if best_value == INFINITY: break if best_value == INFINITY: break return best_move
额外优化点
- 补充剪枝后的外层循环break,提升算法运行效率
- 简化胜负评分逻辑,确保AI优先选择最快获胜路径,同时优先阻断人类的即时获胜路线
内容的提问来源于stack exchange,提问作者Mike McRoberts
相关产品推荐
相关产品推荐

