Mi objetivo es codificar un motor de ajedrez algo bueno, en la siguiente posición es un mate en 2 que el motor debería encontrar fácilmente con su profundidad de 4-5.
El primer movimiento que hace la IA es Ta2 para atrapar al rey blanco, el rey blanco va a f1 y en lugar de dar mate, la IA mueve la torre a 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]; } } }Esto se debe a que ve que cualquier movimiento ganará, y no tienes una condición que le diga al módulo que es mejor dar mate en 1 movimiento que en 5 movimientos. Si al final de una búsqueda encuentra que tiene 0 movimientos legales y está en jaque, entonces está en jaque mate. En este caso, desea enviar una puntuación de jaque mate (valor negativo grande) y agregar la capa de esto. De esta forma, será mejor dar mate en menos movimientos que en una mayor cantidad de movimientos.
Le sugiero que opte por Negamax alogirthm en lugar de minimax. Significará mucho menos código y mucho más fácil de depurar.