Моя цель состоит в том, чтобы закодировать несколько неплохой шахматный движок, в следующей позиции это мат в 2, который движок должен легко найти с его глубиной 4-5.
Первым ходом, который делает ИИ, является Ra2, чтобы поймать белого короля, белый король идет на f1, и вместо мата ИИ перемещает ладью на c2.
var initial_depth = depth;
var bestMove = null;
var nodes = 0;
var ret = await minimax(position, depth, alpha, beta, maximizingPlayer);
console.info("nodes visited: " + nodes);
return ret;
async function minimax(position, depth, alpha, beta, maximizingPlayer) {
nodes++;
if (maximizingPlayer) {
var validMoves = await getValidMoves(position, ArrtoFEN(position) + " w");
} else {
var validMoves = await getValidMoves(position, ArrtoFEN(position) + " b");
}
if (validMoves.length < 1 || depth == 0) {
var eval = await getEval(position);
return [eval, null];
}
if (maximizingPlayer) {
var maxEval = Number.NEGATIVE_INFINITY;
for (var i = 0; i < validMoves.length; i++) {
var move = validMoves[i];
var testbrd = makeMove(move, position) //not the actual code. shortend for Readability
var eval = await minimax(testbrd, depth - 1, alpha, beta, false);
if (eval[0] > maxEval) {
maxEval = eval[0];
if (initial_depth == depth) {
bestMove = move;
console.info("current bestmove: " + bestMove);
}
}
alpha = Math.max(alpha, eval[0]);
if (beta <= alpha) {
break;
}
}
return [maxEval, bestMove];
} else {
var minEval = Number.POSITIVE_INFINITY;
for (var i = 0; i < validMoves.length; i++) {
var move = validMoves[i];
var testbrd = makeMove(move, position)//not the actual code. shortend for Readability
var eval = await minimax(testbrd, depth - 1, alpha, beta, true);
if (eval[0] < minEval) {
minEval = eval[0];
if (initial_depth == depth) {
bestMove = move;
console.info("current bestmove: " + bestMove);
}
}
beta = Math.min(beta, eval[0]);
if (beta <= alpha) {
break;
}
}
return [minEval, bestMove];
}
}
}
Это потому, что он видит, что любой ход выиграет, и у вас нет условия, говорящего движку, что лучше сделать мат в 1 ход, чем в 5 ходов. Если в конце поиска вы обнаружите, что у вас 0 допустимых ходов и вы находитесь под шахом, то вам поставлен мат. В этом случае вы хотите отправить обратно счет мата (большое отрицательное значение) и добавить из него слой. Таким образом, вам будет проще поставить мат за меньшее количество ходов, чем за большее количество ходов.
Я предлагаю вам использовать алогиртм Negamax вместо минимакса. Это будет означать гораздо меньше кода и гораздо более простую отладку.
Круто, приятно слышать, что это работает!
Спасибо за комментарий, я заставил функцию Eval возвращать значение +-1000 при мате и добавил к этому глубину, тем самым отдавая предпочтение «быстрому» мату.