Minimax算法不适合国际象棋
Minimax algorithm doesnt go for mate in chess
我的目标是编写一个还算不错的国际象棋引擎,在下面的位置,它是 2 中的一个伙伴,引擎应该很容易找到它的深度为 4-5。
AI 的第一步是 Ra2 诱捕白王,白王走到 f1,AI 没有交配,而是把车搬到了 c2。
var initial_depth = depth;
var bestMove = null;
var nodes = 0;
var ret = await minimax(position, depth, alpha, beta, maximizingPlayer);
console.log("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.log("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.log("current bestmove: " + bestMove);
}
}
beta = Math.min(beta, eval[0]);
if (beta <= alpha) {
break;
}
}
return [minEval, bestMove];
}
}
}
这是因为它看到任何一步都会获胜,并且您没有条件告诉引擎在 1 步内完成配对比在 5 步内完成配对更好。如果在搜索结束时发现您有 0 个合法移动并且您处于检查状态,那么您将被检查。在这种情况下,您想要发回将死分数(大的负值)并从中添加层。这样,与大量移动相比,更少的移动交配效果更好。
我建议你使用 Negamax alogirthm 而不是 minimax。这意味着更少的代码和更容易调试。
我的目标是编写一个还算不错的国际象棋引擎,在下面的位置,它是 2 中的一个伙伴,引擎应该很容易找到它的深度为 4-5。
AI 的第一步是 Ra2 诱捕白王,白王走到 f1,AI 没有交配,而是把车搬到了 c2。
var initial_depth = depth;
var bestMove = null;
var nodes = 0;
var ret = await minimax(position, depth, alpha, beta, maximizingPlayer);
console.log("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.log("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.log("current bestmove: " + bestMove);
}
}
beta = Math.min(beta, eval[0]);
if (beta <= alpha) {
break;
}
}
return [minEval, bestMove];
}
}
}
这是因为它看到任何一步都会获胜,并且您没有条件告诉引擎在 1 步内完成配对比在 5 步内完成配对更好。如果在搜索结束时发现您有 0 个合法移动并且您处于检查状态,那么您将被检查。在这种情况下,您想要发回将死分数(大的负值)并从中添加层。这样,与大量移动相比,更少的移动交配效果更好。
我建议你使用 Negamax alogirthm 而不是 minimax。这意味着更少的代码和更容易调试。