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

时间:2017-06-03 16:47:39

标签: javascript algorithm tic-tac-toe minimax

我一直在尝试使用minimax算法进行我的tic tac toe游戏,让我的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 个答案:

答案 0 :(得分:0)

如果您看到每个moveVal的{​​{1}},您会看到它为零。
那是因为在minimax函数中你调用i,当false返回0时 您的计划存在的问题是,isMovesLeft始终会返回isMovesLeft 你应该把它改成:

false

此更改应该让您的程序获得6作为最佳移动。

参数function isMovesLeft(board){ for (var i = 0; i<board.length; i++){ if (board[i] =='-'){ return 'true'; } } return false; } 永远不会在任何地方使用 您可以在返回分数时使用它:depth
这将确保失败/获胜的短期后果比长期更有效。