我最近尝试为四连棋实现Minimax算法,但无法使其正常工作。以下是我的heuristic
、AI
和minimax
代码。完整代码在这里。我不知道问题出在哪里,导致无法做出正确的移动。
int heuristic(int s[6][7]) { int result = 0; int i, j; //检查水平方向 for(i=0; i<6; i++) for(j=0; j<=7-4; j++){ if(s[i][j]!= 2 && s[i][j+1]!= 2 && s[i][j+2]!= 2 && s[i][j+3]!= 2) result++; if(s[i][j]!= 1 && s[i][j+1]!= 1 && s[i][j+2]!= 1 && s[i][j+3]!= 1) result--; } //检查垂直方向 for(i=0; i<=6-4; i++) for(j=0; j<7; j++){ if(s[i][j]!= 2 && s[i+1][j]!= 2 && s[i+2][j]!= 2 && s[i+3][j]!= 2 ) result++; if(s[i][j]!= 1 && s[i+1][j]!= 1 && s[i+2][j]!= 1 && s[i+3][j]!= 1 ) result--; } return result;}int minimax(int board[R][C], int depth, int turn /*1 or 2*/) { int e; int col, best; int n; int player; if((e=endgame(board, player))) { if(e==3) return 0; if(e==turn) return 10000; else return -10000; } if(depth==0) return ((turn==1) ? heuristic(board) : -heuristic(board)); best = -10000; for(col=0; col < 7; col++) //检查每个移动 if(board[6-1][col]==0) { //确保列不是空的 put(board, col, turn); n = minimax(board, depth-1, 3-turn); if(turn==1) { if ( -n > best ) best = -n; } else { //turn==2 if ( -n > best ) best = -n; } rmv(board, col); } return best;}int ai(int board[R][C], int depth) { int col, move; int n, val = -10000-1; for(col=0; col < 7; col++) if(board[6-1][col]==0) { put(board, col, 2); n = minimax(board, depth, 1); if ( -n > val ) { val = -n; move = col; } rmv(board, col); } return move;}
回答:
查看你在Dropbox上的代码,你有以下内容:
void rmv(int board[6][7], int column) { int i; for (i=R-1; i>=0; i--){ if (board[i][column] != 0) { board[i][column] = 0; } }}
循环中没有break语句,所以每次你撤销移动时都会删除该列中的所有棋子。
此外,我认为在平局检测代码中的坐标顺序可能有误:
for(i=0; i<7; i++) if(s[i][6-1]==0) return 0;
我认为应该这样写:
for(i=0; i<7; i++) if(s[6-1][i]==0) return 0;
结束游戏检测代码看起来也有些奇怪:
int player;if((e=endgame(board, player)))
这里传递了一个未初始化的变量player到endgame函数中,这似乎是不正确的做法。