Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript中connect-four的minimax算法辅助_Javascript_Algorithm_Minimax - Fatal编程技术网

Javascript中connect-four的minimax算法辅助

Javascript中connect-four的minimax算法辅助,javascript,algorithm,minimax,Javascript,Algorithm,Minimax,我试图在我的connect four游戏中使用minimax算法创建人工智能,但我很难让它正常工作。我相信我已经很接近了,但是我仍然无法把它纠正过来。有人能帮我解决任何错误吗?我意识到我的代码不是很好,因为我对Javascript还不是很有效,这就是为什么我想尝试一下。如果我完全偏离了轨道,有人能告诉我更好的方法吗?提前谢谢 编辑:我已将下面的代码替换为更新的代码。它现在“工作”到给我AI动作,但问题是它们不是“智能”动作。我看过无数的minimax定义,我觉得我已经正确地实现了它。即使我到了7

我试图在我的connect four游戏中使用minimax算法创建人工智能,但我很难让它正常工作。我相信我已经很接近了,但是我仍然无法把它纠正过来。有人能帮我解决任何错误吗?我意识到我的代码不是很好,因为我对Javascript还不是很有效,这就是为什么我想尝试一下。如果我完全偏离了轨道,有人能告诉我更好的方法吗?提前谢谢

编辑:我已将下面的代码替换为更新的代码。它现在“工作”到给我AI动作,但问题是它们不是“智能”动作。我看过无数的minimax定义,我觉得我已经正确地实现了它。即使我到了7英尺深的地方,一个5岁的孩子也能打败它。任何帮助都将不胜感激

    function getBestMove(currBoard,depth,who) {
        var opp;
        //Get opponent for next piece
        if(who == 'a') {
            opp = 'p';
        } else {
            opp = 'a';
        }

        var tBoard = new Array(rows);
        for(var i=0; i<tBoard.length; i++) {
            tBoard[i] = new Array(cols);
        }

        var moves = new Array(aiOpenCols.length);
        //Drop each piece and use minimax function until depth == 0
        for(var i=0; i<aiOpenCols.length; i++) {
            for(var j=0; j<rows; j++) {
                for(var k=0; k<cols; k++) {
                    tBoard[j][k] = currBoard[j][k];
                }
            }
            tBoard = dropPiece(aiOpenCols[i],who,tBoard);
            moves[i] = minimax(tBoard,(+depth - 1),opp,aiOpenCols[i]);
        }

        var bestAlpha = -100000;    //Large negative
        //Use random column if no moves are "good"
        var bestMove = Math.floor(Math.random() * aiOpenCols.length);
        bestMove = +aiOpenCols[bestMove];
        //Get largest value from moves for best move
        for(var i=0; i<aiOpenCols.length; i++) {
            if(+moves[i] > bestAlpha) {
                bestAlpha = moves[i];
                bestMove = aiOpenCols[i];
            }
        }

        bestMove++; //Offset by 1 due to actual drop function
        return bestMove;
    }
    function minimax(currBoard,depth,who,col) {
        //Drop current piece, called from getBestMove function
        currBoard = dropPiece(col,who,currBoard);

        //When depth == 0 return heuristic/eval of board
        if(+depth == 0) {
            var ev = evalMove(currBoard);
            return ev;
        }
        var alpha = -100000;    //Large negative
        var opp;
        //Get opponent for next piece
        if(who == 'a') {
            opp = 'p';
        } else {
            opp = 'a';
        }

        //Loop through all available moves
        for(var i=0; i<aiOpenCols.length; i++) {
            var tBoard = new Array(rows);
            for(var i=0; i<tBoard.length; i++) {
                tBoard[i] = new Array(cols);
            }
            for(var j=0; j<rows; j++) {
                for(var k=0; k<cols; k++) {
                    tBoard[j][k] = currBoard[j][k];
                }
            }
            //Continue recursive minimax until depth == 0
            var next = minimax(tBoard,(+depth - 1),opp,aiOpenCols[i]);
            //Alpha = max(alpha, -minimax()) for negamax
            alpha = Math.max(alpha, (0 - +next));
        }
        return alpha;
    }
    function evalMove(currBoard) {
        //heuristic function
        //AI = # of 4 streaks + # of 3 streaks + # of 2 streaks - # of 3 streaks opp - # of 2 streaks opp           
        var fours = checkFours(currBoard,'b') * 1000;
        var threes = checkThrees(currBoard,'b') * 100;
        var twos = checkTwos(currBoard,'b') * 10;
        var oppThrees = checkThrees(currBoard,'r') * 100;
        var oppTwos = checkTwos(currBoard,'r') * 10;

        var scores = fours + threes + twos - oppThrees - oppTwos;

        //If opponent wins, return large negative
        var oppFours = checkFours(currBoard,'r');
        if(+oppFours > 0) {
            return -100000;
        } else {
            return scores;
        }
    }
    function dropPiece(col,who,currBoard) {
        for(var i=0; i<currBoard.length; i++) {
            if(currBoard[i][col] != 'w') {
                //Make sure column isn't full
                if(i != 0) {
                    if(who == 'p') {
                        currBoard[i-1][col] = 'r';
                    } else {
                        currBoard[i-1][col] = 'b';
                    }
                    break;
                }
            }
            //If column is empty, place in first row
            if(i == (currBoard.length - 1)) {
                if(who == 'p') {
                    currBoard[i][col] = 'r';
                } else {
                    currBoard[i][col] = 'b';
                }
            }
        }
        return currBoard;
    }
函数getBestMove(currBoard、depth、who){
var-opp;
//让对手下一个棋子
如果(谁=‘a’){
opp='p';
}否则{
opp='a';
}
var tBoard=新阵列(行);

对于(var i=0;i你的评估函数是给没有价值的位置特征赋值。一行中有两个相邻的单元格没有价值。如果第四个单元格可以被对手占据而不允许在其他地方获胜,那么一行中有三个单元格也没有价值


简化。对于Connect Four,您只需要关心该位置是赢还是输,或者该位置在下一步是否可以赢或输。如果是赢,则返回一个较大的正值。如果是输,则返回一个较大的负值。如果该位置在下一步可以赢或输,则将该位置的搜索深度扩展一层ch并再次调用minimax(),返回结果。后者将避免所有固定深度的minimax搜索都会受到的影响。否则返回零。

此代码:var eval=evalMove(currBoard,who);生成错误,重命名yout变量。这是因为
eval
在javascript中是一个变量名,所以不能将其用作变量名。如果在浏览器JS控制台中运行以下命令,则可以看到它:eval;eval(“x=2;console.log(x);”;var eval=5;eval;eval(“x=2;console.log(x);”);那确实是个问题,谢谢你指出。我的人工智能在“智能”方面仍然存在问题,但这可能是我遇到的几个问题之一。我必须纠正我自己,我只是注意到你没有使用eval内置函数,所以这不会影响你的算法的结果。这不是一个bug,但肯定是一个糟糕的做法。我本来也这么想,但因为我没有太多使用Javascript,所以我不知道它有一个eval()函数。谢谢你告诉我。我认为我的主要问题是我的启发式函数。我试着让它再做一些检查,似乎我的人工智能“稍微”好了一些。我浏览了一下维基上的算法,它看起来还可以。启发式是需要改进的主要地方(谷歌)。另一个奇怪的东西是一元加号,你使用(+depth+aiOpenCols[i],+moves[i]),我在其中找不到。我要试试这个,它很有道理,我不知道地平线效应。谢谢你的帮助!