为什么我得到"最大呼叫堆栈大小超过"错误

时间:2017-08-22 21:27:37

标签: javascript algorithm tic-tac-toe minimax

我正在制作一个tic tac toe游戏的minimax部分,并且我一直在超过"最大调用堆栈大小"错误。我将错误隔离到#110行,这是emptyIndexies(board)函数。但是我没有看到这个功能有什么问题。我在控制台上测试了它,当我点击它时,电路板似乎更新了;但是,计算机无法正常工作。这是代码

var board = [0, 1, 2, 3, 4, 5, 6, 7, 8];

var player, sqrId, user, computer, row, col;
const ARR_LENGTH = 9;

$(document).ready(function() {
  //1 checkbox event listener
  $(".checkBox").click(function() {
    if($(this).is(":checked")) {
      user = $(this).val();
      player = user;
      computer = (user == 'X') ? 'O' : 'X';
    }
  });

  //2 square even listener 
  $(".square").click(function() {
    sqrId = $(this).attr("id");
    playerMove();
    minimax(board);
    if(checkWinner(board, turn)) {
      alert(turn+" Wins the game!");
      resetBoard();
    }    
    if(!checkDraw()) {
      alert("It's a draw!");
    } 
    player = (player == user) ? computer : user;
  });

  //reset board
  $(".reset").click(function() {
    resetBoard();
  })

});

//player move
function playerMove() {
  if($("#"+sqrId).text() == "") {
      $("#"+sqrId).text(player);
      board[sqrId] = player;   
      console.log(board);
    }
    else {
      alert("Wrong move");
    }    
}


/* computer AI generate random number between 0 - 8  */
function computerAI() {
  var random;
  var min = 0, max = 8;
  do {
    random = Math.floor(Math.random() * (max + min));
  }while($("#"+random).text() != "")
  $("#"+random).text(computer);
  row = getRow();
  col = getCol();
  board[row][col] = computer;
}

//getting row number 
function getRow() {
  return Math.floor(sqrId / ARR_LENGTH);
}

//getting col number
function getCol() {
  return sqrId % ARR_LENGTH;
}

/* checking for winner */
// winning combinations using the board indexies
function winning(board){
 if (
 (board[0] == player && board[1] == player && board[2] == player) ||
 (board[3] == player && board[4] == player && board[5] == player) ||
 (board[6] == player && board[7] == player && board[8] == player) ||
 (board[0] == player && board[3] == player && board[6] == player) ||
 (board[1] == player && board[4] == player && board[7] == player) ||
 (board[2] == player && board[5] == player && board[8] == player) ||
 (board[0] == player && board[4] == player && board[8] == player) ||
 (board[2] == player && board[4] == player && board[6] == player)
 ) {
 return true;
 } else {
 return false;
 }
}

function resetBoard() {
  $(".square").text("");
  $(".checkBox").prop("checked", false); 
  user = "";
  turn = "";
  computer = "";
  for(var i = 0; i < ARR_LENGTH; i++) {
    board[i] = "";
  }
}

// returns list of the indexes of empty spots on the board
function emptyIndexies(board){
  return  board.filter(s => s != "O" && s != "X");
}

// the main minimax function
function minimax(newBoard, player){  
  //available spots
  var availSpots = emptyIndexies(newBoard);

  // checks for the terminal states such as win, lose, and tie 
  //and returning a value accordingly
  if (winning(newBoard, user)){
     return {score:-10};
  }
    else if (winning(newBoard, computer)){
    return {score:10};
    }
  else if (availSpots.length === 0){
    return {score:0};
  }

  // an array to collect all the objects
  var moves = [];

  // loop through available spots
  for (var i = 0; i < availSpots.length; i++){
    //create an object for each and store the index of that spot 
    var move = {};
    move.index = newBoard[availSpots[i]];

    // set the empty spot to the current player
    newBoard[availSpots[i]] = player;

    /*collect the score resulted from calling minimax 
      on the opponent of the current player*/
    if (player == computer){
      var result = minimax(newBoard, user);
      move.score = result.score;
    }
    else{
      var result = minimax(newBoard, computer);
      move.score = result.score;
    }

    // reset the spot to empty
    newBoard[availSpots[i]] = move.index;

    // push the object to the array
    moves.push(move);
  }

  // if it is the computer's turn loop over the moves and choose the move with the highest score
  var bestMove;
  if(player === computer){
    var bestScore = -10000;
    for(var i = 0; i < moves.length; i++){
      if(moves[i].score > bestScore){
        bestScore = moves[i].score;
        bestMove = i;
      }
    }
  }else{

// else loop over the moves and choose the move with the lowest score
    var bestScore = 10000;
    for(var i = 0; i < moves.length; i++){
      if(moves[i].score < bestScore){
        bestScore = moves[i].score;
        bestMove = i;
      }
    }
  }

// return the chosen move (object) from the moves array
  return moves[bestMove];
}

0 个答案:

没有答案