Search code examples
javascriptrandom

Efficient method for generating a unique random number that isn't in an exclusion array


I am making a snake game in javascript and I need a way to choose a random position for the fruit (a single number on which modulus is applied to get the x and y numbers) but the position should not overlap with positions the snake is already covering. I'm currently using recursion to do this:

function random(min = 0, max = 100, exclude = []) {
  let r = Math.round(Math.random() * (max - min)) + min;

  return exclude.includes(r) ? random(...arguments) : r;
}

When the snake covers a large portion of the board leaving only a few spaces for the fruit, this would take a lot of cycles to return a valid number.

Is there a better method to do this or is this method good enough?


Solution

  • Create an array of "valid" numbers and select a random member of it:

    function random(min = 0, max = 100, exclude = []) {
        let free = []
        for (let r = min; r <= max; r++) {
            if (!exclude.includes(r))
                free.push(r)
        }
        return free[Math.floor(Math.random() * free.length)]
    }
    

    This way there will be no need for trial and error loops.