具有 minimax 的 Tic Tac Toe 机器人无法找到最佳动作

问题描述

我正在尝试按照 freecodecamp 的教程使用 minimax 算法制作井字游戏。但是机器人无法找到获胜的动作。我尝试将代码与其他人的代码进行比较,但没有发现任何错误

我检查了该函数返回的走法,它返回了一个分数为 -10 的走法,即使分数为 10 的走法可用。

请告诉我我的代码有什么问题。

function minimax(gameBoard,player){
    if(checkWin(gameBoard,bot)) return {score: 10};
    if(checkWin(gameBoard,human)) return {score: -10};
    
    var emptyCells = board.filter(e => typeof e === "number");
    
    if(emptyCells.length===0) return {score: 0};
    
    var possibleMoves = [];
    
    for(var i=0;i<emptyCells.length;i++){
        var move = {};
        move.id = gameBoard[emptyCells[i]];
        
        gameBoard[emptyCells[i]] = player;
        
        if(player === bot){
            move.score = minimax(gameBoard,human).score;
        }else{
            move.score = minimax(gameBoard,bot).score;
        }
        
        gameBoard[emptyCells[i]] = move.id;
        possibleMoves.push(move);
        
        var bestMove;
        if(player === bot){
            var bestscore = -100;
            for(var i=0;i<possibleMoves.length;i++){
                if(possibleMoves[i].score>bestscore){
                    bestscore = possibleMoves[i].score;
                    bestMove = i;
                }
            }
        }
        else{
            var bestscore = 100;
            for(var i=0;i<possibleMoves.length;i++){
                if(possibleMoves[i].score<bestscore){
                    bestscore = possibleMoves[i].score;
                    bestMove = i;
                }
            }
        }
    }
    return possibleMoves[bestMove];
}

解决方法

假设您的函数 checkWin 没有错误,并且您在初始调用中传递的参数有效,那么您的代码中存在以下两个问题:

  • 在以下语句中引用了 board,它实际上应该是 gameBoard

    var emptyCells = board.filter(e => typeof e === "number");
    
  • 确定 bestMove(以 var bestMove; 开头)的代码部分不应位于循环内。您希望首先将所有走法添加到possibleMoves,然后仅然后迭代这些走法以找到最佳走法。但是现在,每次向 possibleMove 添加一个走法时,您都会搜索最佳走法。更糟糕的是,您使用了相同 循环变量 i,它已在外循环中使用,这将完全混淆您的外循环。

解决这两个问题应该可以解决您描述的问题。