Реализация Tic Tac Toe Negamax.
Я пытаюсь реализовать функцию поиска negamax для приложения в крестики-нолики, но она не возвращает оптимальных значений, а, кажется, угадывает почти случайно. Вот соответствующая часть моего кода:
public int negamax(Result result, Token token) {
if (result == Result.WIN) {
return 1;
} else if (result == Result.DRAW) {
return 0;
}
int best = -1;
for (Coordinate move : Board.getAvailableMoves()) {
Token other = token.getOther();
Result r = Board.makeMove(move, other);
int eval = -negamax(r, other);
Board.unmakeMove(move);
if (eval > best) {
best = eval;
}
}
return best;
}
public Coordinate getNegamaxMove(Token token) {
int score = -1;
Coordinate bestMove = null;
for (Coordinate move : Board.getAvailableMoves()) {
Result result = Board.makeMove(move, token);
int newScore = negamax(result, token);
Board.unmakeMove(move);
if (newScore >= score) {
score = newScore;
bestMove = move;
}
}
return bestMove;
}
Важно отметить, что я передаю не доску в качестве параметра, а результат хода, который может быть WIN, DRAW, VALID или OCCUPIED (последние 2 не относятся к текущему обсуждению), которые все само за себя. Класс Coordinate содержит только значения строк и столбцов перемещения.
Большое спасибо:)
1 ответ
Мне удалось заставить его работать, было 2 проблемы с методом Negamax. Прежде всего, токен должен быть изменен перед циклом всех доступных ходов, а не внутри цикла. Во-вторых, поскольку я проверяю лучший ход в методе getNegamaxMove, в методе negamax я должен отслеживать худший ход вместо лучшего. Вот рабочая реализация со старыми частями, закомментированными для сравнения:
public int negamax(Result result, Token token) {
if (result == Result.WIN) {
return 1;
} else if (result == Result.DRAW) {
return 0;
}
int worst = 1;
// int best = -1
Token other = token.getOther();
for (Coordinate move : Board.getAvailableMoves()) {
// Token other = token.getOther();
Result r = Board.makeMove(move, other);
int eval = -negamax(r, other);
Board.unmakeMove(move);
// if (eval > best) {
// best = eval;
// }
if (eval < worst) {
worst = eval;
}
}
// return best
return worst;
}