2016-09-24 2 views
0

Итак, я пытаюсь сделать игру Tic Tac Toe после this учебника. Когда я запускаю его и посмотреть на Дев инструментов Chrome, он говорит Uncaught RangeError: Maximum call stack size exceeded, и указать мне на линии этой функции:Ошибка «Максимальный размер стека вызовов»

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; 
    } 
}; 

Я не понимаю, почему. Here's полный код, ошибка появляется, когда вы нажимаете Play, затем OK затем на одной из ячеек. Here он размещен на другом сайте, если это помогает.

Спасибо!

+0

Неверная скрипка, или вы не скопировали фактический код. Получение «TypeError: Невозможно прочитать статус свойства« неопределенного », а не то, что вы говорите. –

+0

@ShadowWizard yep, нажмите play и ok, а затем на любую из ячеек. –

ответ

1

Существует опечатка в методе 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 вместо этого.

+0

Я не думаю, что это была ошибка; учебник, который я выполняю, делает то же самое. –

+0

Я пришел к такому же выводу. Это правильный ответ (+1). 'this.movePosition' всегда будет' undefined'. Проверьте его с помощью отладки. Учебники не идеальны. – trincot

+0

Спасибо, это похоже на проблему. –

0

Слишком рекурсия, в строке скрипта 395 вы вызываете функцию minimax в рекурсии.

var nextScore = miniMax(nextState); 

Вы должны остановить рекурсию до окончания работы или преобразовать рекурсию в цикл.

+0

Извините за недостаток знаний, но как это сделать? –

0

В AIaction = function(pos) у вас есть два написания для того, что должно быть таким же movePosition свойства:

this.oMovesPosition = pos; 

и:

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

Поскольку они имеют разные свойства, то вторая линия всегда будет эквивалентна этим :

next.board[undefined] = state.turn; 

... и поэтому плата никогда не была фактически меняется. Как следствие, совет никогда не считается терминалом, и ваша рекурсия никогда не прекращается.

Смежные вопросы