开发者问题收集

“超出最大调用堆栈大小”错误

2016-09-24
382

因此,我尝试按照 教程制作井字游戏。当我运行它并查看 Chrome 开发工具时,它显示 Uncaught RangeError: Maximum call stack size reached ,并将我指向此函数的行:

var State = function(oldState) {
    this.turn = "";
    this.oMovesCount = 0;
    this.result = "still running";
    this.board = [];


    //get the information from the previous state to use it for following states
    if (typeof oldState !== "undefined") {
        var len = oldState.board.length;
        this.board = new Array(len);
        for (var i = 0; i < len; i++) {
            this.board[i] = oldState.board[i];
        }
        this.oMovesCount = oldState.oMovesCount;
        this.result = oldState.result;
        this.turn = oldState.turn;
    }

    //change to X or O accordingly
    this.advanceTurn = function() {
        //Was it just X's turn? If so, change to O. If not, change to X.
        this.turn = this.turn === "x" ? "o" : "x";
    };

    //checks for victory
    this.result = "still running";
    this.isTerminal = function() {
        var B = this.board;

        //check to see if there has been a victory
        //check rows
        for(var i = 0; i <= 6; i = i + 3) {
            if(B[i] !== "E" && B[i] === B[i+1] && B[i+1] == B[i+2]) {
                this.result = B[i] + " has won!";
                return true;
            }
        }
        //check columns
        for(var i = 0; i <= 2 ; i++) {
            if(B[i] !== "E" && B[i] === B[i+3] && B[i+3] === B[i+6]) {
                this.result = B[i] + " has won!";
                return true;
            }
        }
        //check diagonals
        for(var i = 0, j = 4; i <= 2 ; i = i + 2, j = j - 2) {
            if(B[i] !== "E" && B[i] == B[i+j] && B[i+j] === B[i + 2*j]) {
                this.result = B[i] + " has won!";
                return true;
            }
        };

        //if there have been no wins, check the number of empty cells
        //if there are no empty cells, it's a draw
        var available = this.emptyCells();
        if (available.length == 0) {
            this.result = "draw";
            return true;
        }
        else {
            return false;
        }
    };
    //keeps track of how many empty cells there are on the board
    this.emptyCells = function() {
        var indxs = [];
        for (var i = 0; i < 9; i++) {
            if (this.board[i] === "E") {
                indxs.push(i);
            }
        }
        return indxs;
    } 
};

我不明白为什么。 这是 完整代码,当您单击 Play ,然后单击 OK ,然后在其中一个单元格上单击时,会显示错误。 这里 ,如果有帮助,它托管在另一个网站上。

谢谢!

3个回答

AIAction 方法中有一个拼写错误:

this.oMovesPosition = pos; //the position on the board where the O would be placed
this.minimaxVal = 0; //the minimax value of the state that the action leads to

this.applyTo = function(state) {
    var next = new State(state);

    //if the current turn in the current state is O, increment .oMovesCount
    next.board[this.movePosition] = state.turn;
    if (state.turn === "o") {
        next.oMovesCount++;
    }
    next.advanceTurn();
    return next;
};

请注意第一行中的 this.oMovesPosition,但 applyTo 方法却引用了 this.movePosition。

Nicolas Galler
2016-09-24

对于递归,在第 395 行中,您在递归中调用了函数 minimax。

var nextScore = miniMax(nextState);

您必须在内存耗尽之前停止递归,或者将递归转换为循环。

Stefano Balzarotti
2016-09-24

AIaction = function(pos) 中,对于应该相同的 movePosition 属性,您有两种拼写:

this.oMovesPosition = pos;

和:

next.board[this.movePosition] = state.turn;

由于它们是不同的属性,因此第二行将始终等同于此:

next.board[undefined] = state.turn;

... 因此棋盘实际上从未改变。因此,棋盘永远不会被视为终端,并且您的递归永远不会停止。

trincot
2016-09-24