Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

141
Views
how to avoid recursion or to fix the problem?

Teaching JS trying to do a ticatactoe game and got a problem with recursion, specifically with 'Maximum call stack size exceeded'.

When I try to make a random move by the computer player I make a random number, which then will be checked of his value in array called gameState. So, if this value has defined already (there are X or O mark in a cell), I need to generate a random number again. So I need to stop this infinite loop when all cells are marked or I'll get an error 'Maximum call stack size exceeded'.

Can you please take a look, am I do the right thing or it is generally wrong? Actually, I thought about another implementation of this game scene, but I thought if i've started with that I should lead this to the end


let gameState = ["", "", "", "", "", "", "", "", "",];
let playerAi = "O";

// ai's turn
function playerAiTurn() {
    let randomNum = Math.floor(Math.random() * gameState.length);
    if (gameState[randomNum] === '') {
    gameState[randomNum] = playerAi;
    document.getElementById(randomNum).innerHTML = playerAi;
    resultCheck();
    } else {
        playerAiTurn()
    };
};
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

There's a very slim chance that repeated random calls will keep on getting the same number, so it's not strictly speaking correct to simply keep rolling random numbers (even though in practice it's highly unlikely to ever be encountered).

To avoid the situation with certainty, one should only take a random number based on the unused places. For example:

let gameState = ["", "", "", "", "", "", "", "", "",];
let playerAi = "O";

// ai's turn
function playerAiTurn() {
  let unusedPlaces = [];
  for(let i=0; i<gameState.length; i++) {
    if( gameState[i] === "") unusedPlaces.push(i); 
  }
  if( unusedPlaces.length > 0 ){
    let randomUnusedPlace = unusedPlaces [ Math.floor(Math.random() * unusedPlaces.length) ];
    gameState[randomUnusedPlace] = playerAi
    document.getElementById(randomUnusedPlace).innerHTML = playerAi; 
  }

  resultCheck();
}

No recursive calls.

about 4 years ago · Juan Pablo Isaza Report

0

You have to check when the game has ended and stop the recursive calls. I don't know the implementation of resultCheck but it should return information about whether the game is finished or not. If it is finished, don't do the recursive call.

That being said, the performance of your code is unpredictable because it generates random numbers even before knowing if the resulting slot is available. You could optimize it like this:

const gameState = ["", "", "", "", "", "", "", "", "",];
const playerAi = "O";

function playerAiTurn() {
    const emptySlots = Array.from(gameState.entries()).filter(([, x]) => x === '');
    if(!emptySlots.length)
        return; //Game over
    const randomNum = Math.floor(Math.random() * emptySlots.length);
    const [index] = emptySlots[randomNum];
    gameState[index] = playerAi;
    document.getElementById(index).innerHTML = playerAi;
    resultCheck();
};
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!