我试图使我的minimax算法适用于8x8 Gomoku板,我必须连续匹配5个/ col /对角线才能获胜!我的算法似乎没有正常工作,我无法确定它出错的地方!
我的generateMoves()方法正常工作,它会产生所有合法的动作,所以我知道它并非如此。 minimax返回-1,-1作为最佳移动但当然会抛出非法移动错误,因为你不能在0,0到7,7之间的板上有-1,-1。
感谢任何帮助。感谢。
private int[] minimax(int depth, Color [][] board) {
List<int[]> nextMoves = generateMoves(board);
int bestScore = (me == Color.WHITE) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
int currentScore;
int bestRow = -1;
int bestCol = -1;
if (nextMoves.isEmpty() || depth == 0) {
bestScore = evaluateBoard(board);
} else {
for (int[] move : nextMoves) {
System.out.println(move[0]+","+move[1]+" THIS WAS ATTEMPTED");
board[move[0]][move[1]] = Color.WHITE;
if (me == Color.BLACK) {
currentScore = minimax(depth - 1, board)[0];
if (currentScore > bestScore) {
bestScore = currentScore;
bestRow = move[0];
bestCol = move[1];
}
} else { // oppSeed is minimizing player
currentScore = minimax(depth - 1, board)[0];
if (currentScore < bestScore) {
bestScore = currentScore;
bestRow = move[0];
bestCol = move[1];
}
}
board[move[0]][move[1]] = null;
}
}
return new int[] {bestRow, bestCol};
}
public int evaluateBoard(Color[][] board) {
int score = 0;
// Check all the rows
for (int i = 0; i < 8; i++) {
int blank = 0;
int black = 0;
int white = 0;
for (int j = 0; j < 8 - 5; ++j) {
if (board[i][j] == Color.black) {
black++;
if (board[i][j + 1] == Color.BLACK) {
black++;
if (board[i][j + 2] == Color.BLACK) {
if (board[i][j + 3] == Color.BLACK) {
black++;
if (board[i][j + 4] == Color.BLACK) {
black++;
}
}
}
}
} else if (board[i][j] == Color.WHITE) {
white++;
if (board[i][j + 1] == Color.WHITE) {
white++;
if (board[i][j + 2] == Color.WHITE) {
white++;
if (board[i][j + 3] == Color.WHITE) {
white++;
if (board[i][j + 4] == Color.WHITE) {
white++;
}
}
}
}
}
}
System.out.println(black);
score += scoreChange(black, white);
}
// Check all the columns
for (int j = 0; j < 8; ++j) {
int blank = 0;
int black = 0;
int white = 0;
for (int i = 0; i < 8 - 5; ++i) {
if (board[i][j] == Color.black) {
black++;
if (board[i + 1][j] == Color.BLACK) {
black++;
if (board[i + 2][j] == Color.BLACK) {
black++;
if (board[i + 3][j] == Color.BLACK) {
black++;
if (board[i + 4][j] == Color.BLACK) {
black++;
}
}
}
}
} else if (board[i][j] == Color.WHITE) {
white++;
if (board[i + 1][j] == Color.WHITE) {
white++;
if (board[i + 2][j] == Color.WHITE) {
white++;
if (board[i + 3][j] == Color.WHITE) {
white++;
if (board[i + 4][j] == Color.WHITE) {
white++;
}
}
}
}
}
}
score += scoreChange(black, white);
}
int black = 0;
int white = 0;
// Check diagonal (Second)
for (int i = 7, j = 0; i > 3; --i, ++j) {
if (board[i][j] == Color.black) {
black++;
if (board[i - 1][j + 1] == Color.black) {
black++;
if (board[i - 2][j + 2] == Color.black) {
black++;
if (board[i - 3][j + 3] == Color.black) {
black++;
if (board[i - 4][j + 4] == Color.black) {
black++;
}
}
}
}
} else if (board[i][j] == Color.white) {
white++;
if (board[i - 1][j + 1] == Color.white) {
white++;
if (board[i - 2][j + 2] == Color.white) {
white++;
if (board[i - 3][j + 3] == Color.white) {
white++;
if (board[i - 4][j + 4] == Color.white) {
white++;
}
}
}
}
}
}
score += scoreChange(black, white);
black = 0;
white = 0;
// Check Diagonal (First)
for (int i = 0, j = 0; i < 4; ++i, ++j) {
if (board[i][j] == Color.black) {
black++;
if (board[i + 1][j + 1] == Color.black) {
black++;
if (board[i + 2][j + 2] == Color.black) {
black++;
if (board[i + 3][j + 3] == Color.black) {
black++;
if (board[i + 4][j + 4] == Color.black) {
black++;
}
}
}
}
} else if (board[i][j] == Color.white) {
white++;
if (board[i + 1][j + 1] == Color.white) {
white++;
if (board[i + 2][j + 2] == Color.white) {
white++;
if (board[i + 3][j + 3] == Color.white) {
white++;
if (board[i + 4][j + 4] == Color.white) {
white++;
}
}
}
}
}
}
score += scoreChange(black, white);
return score;
}
private int scoreChange(int black, int white) {
int change;
if (black == 5) {
change = -10000;
} else if (black == 4 && white == 0) {
change = -1000;
} else if (black == 3 && white == 0) {
change = -100;
} else if (black == 2 && white == 0) {
change = -10;
} else if (black == 1 && white == 0) {
change = -1;
} else if (white == 5) {
change = 10000;
} else if (white == 4 && black == 0) {
change = 1000;
} else if (white == 3 && black == 0) {
change = 100;
} else if (white == 2 && black == 0) {
change = 10;
} else if (white == 1 && black == 0) {
change = 1;
} else {
change = 0;
}
return change;
}
答案 0 :(得分:0)
如果玩家是黑人,最好的分数是Integer.Max。目前的分数永远不会大于此,所以最好的动作永远不会设定。对于White来说,问题是一致的:最好的分数是Integer.Min,目前的得分从未变小。
使用调试器查找像这样的错误要容易得多。设置断点,将移动设置为-1,然后前进。当你接触到那些if语句时,当你的代码没有介入时你会感到惊讶。你将仔细研究被比较的值然后意识到你的错误。