Dart实现Minimax算法的井字棋AI出现错误决策求助
问题描述
我用Dart实现了基于Minimax算法的井字棋程序,电脑以“O”方身份尝试最大化得分,但出现错误决策。例如AI建议落子(0,2),但这并非正确决策。当前棋盘状态如下:
代码实现
class Ai { play(state) { return max_Value(state); } // action参数记录到达当前状态的落子位置 List max_Value(List state, {action}) { List v = [null, double.negativeInfinity]; if (terminal(state)) { return [action, utility(state)]; } for (var action in actions(state)) { if (v[1] == 1) return v; v = max(v, min_Value(result(state, action), action: action)); } return v; } List min_Value(List state, {action}) { List v = [null, double.infinity]; if (terminal(state)) { return [action, utility(state)]; } for (var action in actions(state)) { if (v[1] == -1) return v; v = min(v, max_Value(result(state, action), action: action)); } return v; } List min(List prv, List curr) { return prv[1] < curr[1] ? prv : curr; } List max(List prv, List curr) { return prv[1] > curr[1] ? prv : curr; } bool terminal(List state) { // 检查横向获胜 if (state[0][0] == state[0][1] && state[0][0] == state[0][2] && state[0][0] != "") { return true; } if (state[1][0] == state[1][1] && state[1][0] == state[1][2] && state[1][0] != "") { return true; } if (state[2][0] == state[2][1] && state[2][0] == state[2][2] && state[2][0] != "") { return true; } // 检查纵向获胜 if (state[0][0] == state[1][0] && state[0][0] == state[2][0] && state[0][0] != "") { return true; } if (state[0][1] == state[1][1] && state[0][1] == state[2][1] && state[0][1] != "") { return true; } if (state[0][2] == state[1][2] && state[0][2] == state[2][2] && state[0][2] != "") { return true; } // 检查对角线获胜 if (state[0][0] == state[1][1] && state[2][2] == state[0][0] && state[0][0] != "") { return true; } if (state[2][0] == state[1][1] && state[2][0] == state[0][2] && state[2][0] != "") { return true; } // 检查棋盘是否填满 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (state[i][j] == "") { return false; } } } return true; } double utility(List state) { String winner = ""; // 横向判断胜者 if (state[0][0] == state[0][1] && state[0][0] == state[0][2]) { winner = state[0][0]; } if (state[1][0] == state[1][1] && state[1][0] == state[1][2]) { winner = state[1][0]; } if (state[2][0] == state[2][1] && state[2][0] == state[2][2]) { winner = state[2][0]; } // 纵向判断胜者 if (state[0][0] == state[1][0] && state[0][0] == state[2][0]) { winner = state[0][0]; } if (state[0][1] == state[1][1] && state[0][1] == state[2][1]) { winner = state[0][1]; } if (state[0][2] == state[1][2] && state[0][2] == state[2][2]) { winner = state[0][2]; } // 对角线判断胜者 if (state[0][0] == state[1][1] && state[2][2] == state[0][0]) { winner = state[0][0]; } if (state[2][0] == state[1][1] && state[2][0] == state[0][2]) { winner = state[2][0]; } // 返回对应效用值 if (winner == "O") { return 1; } else if (winner == "X") { return -1; } else { return 0; } } List actions(List state) { List acs = []; // 收集所有空位置作为可行落子 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (state[i][j] == "") { acs.add([i, j]); } } } return acs; } List result(List state, List action) { // 复制当前棋盘状态 List newState = [ ["", "", ""], ["", "", ""], ["", "", ""] ]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { newState[i][j] = state[i][j]; } } // 在新状态中执行落子 newState[action[0]][action[1]] = player(state); return newState; } player(List state) { int xnum = 0; int onum = 0; // 统计双方落子数量 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (state[i][j] == "X") { xnum++; } else if (state[i][j] == "O") { onum++; } } } // 判断当前回合玩家 if (xnum > onum) { return "O"; } else { return "X"; } } }
内容的提问来源于stack exchange,提问作者haitham
相关产品推荐
相关产品推荐

