当前位置: 首页 > 知识库问答 >
问题:

javascript minimax算法tic tac toe,并不总是给出最好的动作

谢俊英
2023-03-14

我一直在尝试在我的tic-tac-toe游戏中使用minimax算法,以使我的AI无敌。然而,它并不总是返回最佳移动。

AI = X; human = "O"

var board =  ["x", "x", "-",
               "-", "o", "o",
               "-", "-", "-"]

它给出了上面的指数[2]作为正确的最佳移动。

然而,有了下面的棋盘,它给出的答案是索引[3],这将允许人类玩家在轮到它时获胜。

var boardB = ["x","x","o",
             "-","o","-",
             "-","_","-"];

var player = 'x';
var opponent = 'o';

function isMovesLeft(board){
    for (var i = 0; i<board.length; i++){
        if (board[i] =='-'){
            return 'true';
        }
        else{
            return 'false';
        }
    }
}



function evaluate(){
    for (var i = 0; i < board.length; i += 3) {
        if (board[i] === board[i + 1] && board[i + 1] === board[i + 2]) {
            if (board[i] == player){
                return +10;  
            }
            else if(board[i]== opponent){
                return -10;
            } 
        }
    }
    for (var j = 0; j < board.length; j++) {
        if (board[j] === board[j + 3] && board[j + 3] === board[j + 6]) {
            if (board[j] == player){
                return +10;  
            }
            else if(board[j] == opponent){
                return -10;
            } 
        }
    }


  if ((board[4]==board[0] && board[4]==board[8]) || (board[4]==board[2] && board[4]==board[6])) {
    if (board[4]==player){
        return +10;
    }
    else if (board[4]==opponent){
        return -10;
    }
 }

return 0;
}



function minimax(board, depth, isMax){
    var score = evaluate(board);

    if (score == 10){
        return score;
    }

    if (score == -10){
        return score;
    }

    if (isMovesLeft(board) =="false"){
        return 0;
    }

    if (isMax == "true"){
        var best = -1000;

        for (var i = 0; i< board.length; i++){
            if (board[i]=='-'){
                board.splice(i, 1, player);
                var value = minimax(board, depth+1, "false");
                best = Math.max(best, value);

                board.splice(i, 1, "-");
            }
         }
         return best;  
     }

    else if (isMax == 'false'){
        var best = 1000;
        for (var i = 0; i<board.length; i++){
            if (board[i]=='-'){
             board.splice(i, 1, opponent);
             var value = minimax(board, depth+1, "true");
             best = Math.min(best, value);

             board.splice(i, 1, "-");
            }
         }
        return best;
      }
}

function findBestMove(board){
    var bestVal = -1000;
    var bestMove= -1;

    for (var i = 0; i<board.length; i++){
        if (board[i]=='-'){
            board.splice(i, 1, player);
            var moveVal = minimax(board, 0, "false");

            board.splice(i, 1, "-");

            if (moveVal > bestVal)
            {
                bestMove = i;
                bestVal = moveVal;
            }
        }
    }
    alert("bestVal is : " + bestVal + "<br> best Move is : " + bestMove;)
}

我想知道我的代码出了什么问题。以下是我用作参考的一些网站:

http://www.geeksforgeeks.org/minimax-algorithm-in-game-theory-set-3-tic-tac-toe-ai-finding-optimal-move/

https://blog.vivekpanyam.com/how-to-build-an-ai-that-wins-the-basics-of-minimax-search/

但我仍然不明白为什么它不总是返回最佳移动。我希望有人能把我引向正确的方向。提前谢谢!

共有1个答案

傅星光
2023-03-14

如果你看到每个imoveVal,你会发现它是零。
这是因为在极小值函数中,你调用isMoves↓,当false返回0时。
你的程序的问题是isMoves↓总是返回false
你应该把它改成:

function isMovesLeft(board){
    for (var i = 0; i<board.length; i++){
        if (board[i] =='-'){
            return 'true';
        }
    }
return false;
}  

这个变化应该让你的程序得到6作为最好的移动。

参数depth从未在任何地方使用
您可以在返回分数时使用它:返回分数/深度
这将确保输赢的短期后果比长期后果更有效。

 类似资料:
  • 本文向大家介绍算法题:名人问题,给出最优解法相关面试题,主要包含被问及算法题:名人问题,给出最优解法时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 问题描述: 有n个人他们之间认识与否用邻接矩阵表示(1表示认识,0表示不认识),并A认识B并不意味着B认识A,也就意味着是个有向图。如果一个人是名人,他必须满足两个条件,一个是他不认识任何人,另一个是所有人必须都认识他。 解决问题: 用一个数组

  • 问题内容: 我正在查看一位同事的代码,但遇到一段类似于以下代码的代码: 我相信没有必要,但我很难证明这一点。如果它更具体(,等等)可能很有意义,但是因为我认为这是不必要的。有人可以给我一些原因,这可能导致什么问题,以及为什么这是不好的做法?还是这个代码可以吗? 问题答案: 该声明是方法合同的一部分。定义合同时,您应始终尽可能 精确 。因此,说是个坏主意。 出于同样的原因,这是不好的做法,因为不好的

  • 文档状态: 返回新的CompletableFuture,该Future由运行在在它运行给定操作之后。 然而,据我所知,只向when

  • 我目前使用的是Xcode 8.3.3,如果我使用的是UIWebView,我会遇到这个错误,您可以在下面看到,然后在某些项目中或某些时候WebView不工作,而在其他项目中它会工作。我已经用一个空项目对它进行了测试,是的,是UIWebView导致了这些问题。 objc[11182]:类PLBuildVersion在/Applications/xcode . app/Contents/Develope

  • 我被要求将我的玩家与玩家的打球游戏改进为玩家与电脑对抗的AI打球游戏:为此,我需要编写两个函数:一个获取棋盘和当前玩家的符号,并返回所有可能的未来棋盘列表-每个未来棋盘都是一个包含两个元素的列表:一个是放置符号的位置另一个是放置符号后的板-一圈后的板(我使用的是嵌套的列表板,如下面的代码所示(我在这里收到了帮助) 我需要的第二个函数是计算机转动的函数——它使用第一个函数并通过以下方式之一选择最佳移

  • ConstraintViolationException在将无效调用放入控制器的contructor时引发: