我有一个minimax算法,用于对tic-tac-toe进行alpha beta修剪。我无法为minimax如何回避电路板添加深度限制。当我添加深度限制时,它只能部分工作。例如,如果我先在中间移动,它将在第二步中选择一个失败的位置。
(Computer is O. Player is X.)
_ _ _ o _ _ o _ x o o x
_ x _ _ x _ _ x _ _ x _
_ _ _ _ _ _ _ _ _ _ _ _
但如果我从第一个位置开始,它就可以了。它似乎忽略了我的2行。如果我一起删除深度限制它一直正常工作。如何为算法添加深度限制,使其始终正常工作?为什么它不适用于深度限制?
这是评估部分,没有深度限制,完全适用于minimax方法的顶部:
int score = evaluate(board);
//if maximizer won
if (score == 10) {
return score;
}
//if minimizer won
if (score == -10) {
return score;
}
if (hasCellsLeft(board) == false) {
return 0;
}
这是方法顶部的评估,深度限制:
if (depth == 6||isGameOver(board)) {
return evaluate(board);
}
这是评估方法:
public int evaluate(Cell[] board) {
//rows across
if (isGameOver(board) && endStates.checkWinByRow(board, playerToken) || isGameOver(board) && endStates.checkWinByColumn(board, playerToken) || isGameOver(board) && endStates.checkWinByDiagonal(board, playerToken)) {
return 10;
}
if (isGameOver(board) && endStates.checkWinByRow(board, opponentToken) || isGameOver(board) && endStates.checkWinByColumn(board, opponentToken) || isGameOver(board) && endStates.checkWinByDiagonal(board, opponentToken)) {
return -10;
}
else {
return 0;
}
}
这是 isGameOver方法:
public boolean isGameOver(Cell[] board) {
if (endStates.checkWinByRow(board, playerToken) || endStates.checkWinByColumn(board, playerToken) || endStates.checkWinByDiagonal(board, playerToken)) {
return true;
}
if (endStates.checkWinByRow(board, opponentToken) || endStates.checkWinByColumn(board, opponentToken) || endStates.checkWinByDiagonal(board, opponentToken)) {
return true;
}
return false;
}
以下是 minimax算法:
public int alphaBeta(Cell[] board, int depth, int nodeIndex, boolean isMax, int alpha, int beta) {
if (depth == 6||isGameOver(board)) {
return evaluate(board);
}
if (isMax) {
int best = MIN;
// Recur for left and right children
for (int i=0; i<board.length; i++) {
if (board[i].getToken() == Token.EMPTY) {
board[i].setToken(playerToken);
int val = alphaBeta(board, depth + 1, nodeIndex * 2 + i, false, alpha, beta);
//int best = beta;
best = Math.max(best, val);
alpha = Math.max(alpha, best);
board[i].resetMarker();
// Alpha Beta Pruning
if (beta <= alpha) {
break;
}
}
}
return best;
}
else {
int best = MAX;
// Recur for left and right children
for (int i=0; i<board.length; i++) {
if (board[i].getToken() == Token.EMPTY) {
board[i].setToken(opponentToken);
int val = alphaBeta(board, depth + 1, nodeIndex * 2 + i, true, alpha, beta);
//int best = beta;
best = Math.min(best, val);
beta = Math.min(beta, best);
board[i].resetMarker();
}
// Alpha Beta Pruning
if (beta <= alpha) {
break;
}
}
return best;
}
}