前几天,我用C++为儿子编写了一个井字游戏的控制台游戏。他希望我加入一个电脑玩家,于是我首次尝试使用了Minimax算法。我进行了简单的测试,但实际上一看到程序能输出内容,我就把笔记本电脑交给了儿子,他玩了几分钟。我偶尔看了一下他的屏幕,发现电脑玩家的表现并不最优,我一直在试图调试,但找不到问题出在哪里。我尝试去掉alpha-beta剪枝,但这并没有改变任何结果。
为了提供背景信息,棋盘上电脑玩家是-1,空格是0,玩家是1。
这是Minimax函数:
int minimax(int board[9], int depth, int alpha, int beta, bool isMaxizimaizingPlayer){ bool found = false; for (int i = 0; i < 9; i++) { if (board[i] == 0) { found = true; } } if (!found) { return eval(board); } if (depth == 0 || eval(board) != 0) { return eval(board); } if (isMaxizimaizingPlayer) { int maxEval = -2; for (int spot = 0; spot < 9; spot++) { if (board[spot] == 0) { board[spot] = 1; int e = minimax(board, depth - 1, alpha, beta, false); if (e > maxEval) { maxEval = e; } //if (beta < alpha) //{ // break; //} board[spot] = 0; } } return maxEval; } else { int minEval = 2; for (int spot = 0; spot < 9; spot++) { if (board[spot] == 0) { board[spot] = -1; int e = minimax(board, depth - 1, alpha, beta, true); if (e < minEval) { minEval = e; } //if (beta < alpha) //{ // break; //} board[spot] = 0; } } return minEval; }}
为了完整起见,这是我的评估函数:
int eval(int board[9]) { /*horizontial*/ for (int i = 0; i < 3; i++) { if (board[i * 3] == board[i * 3 + 1] && board[i * 3 + 2] == board[i * 3] && board[i * 3] != 0) { return board[i * 3]; } } /*vertical*/ for (int i = 0; i < 3; i++) { if (board[i] == board[i + 3] && board[i] == board[i + 6] && board[i] != 0) { return board[i]; } } /*Both diags*/ if (board[4] != 0) { if (board[0] == board[4] && board[0] == board[8]) { return board[4]; } if (board[2] == board[4] && board[4] == board[6]) { return board[4]; } } return 0;}
这是初始调用:
int spot = 0; int minEval = 2; for (int i = 0; i < 9; i++) { if (board[i] == 0) { board[i] = -1; int score = minimax(board, 3, -2, 2, false); if (score < minEval) { minEval = score; spot = i; } board[i] = 0; } } std::cout << "The computer went in spot " << spot + 1 << std::endl; board[spot] = -1; printBoard(board);
回答:
看起来你只调用了深度为三的Minimax算法,所以算法只会向前看三步,如果你想要最优的表现,你需要将深度设置为> 9,这样智能体才能始终看到游戏的结局。