In practice, your code will be fine. In theory, it is not guaranteed to terminate, but the probability of that happening is literally negligible.
However, what you are doing is picking a random integer between 1 and 3 (both inclusive), with the number not repeating. With only three possibilities, we could draw up a state machine:
states = {
1: [2, 3],
2: [1, 3],
3: [1, 2] };
if (lastRandom === undefined) {
random = Math.floor(Math.random() * 3) + 1;
}
else {
random = states[lastRandom][Math.floor(Math.random() * 2)];
}
lastRandom = random;
Unfortunately, that involves generating all the states first, which is impractical for larger ranges. There, we could use this more clever approach:
var min = 1;
var max = 3;
if (lastRandom === undefined) {
random = Math.floor(Math.random() * (max - min + 1)) + min;
}
else {
random = Math.floor(Math.random() * (max - min )) + min;
if (random >= lastRandom) random += 1;
}
lastRandom = random;
So if we are choosing the first number, everything works as usual. But for any subsequent number, we choose an integer from a set one smaller (to reflect that one number, the lastRandom
, can't be chosen). If the random number obtained like this is less than the lastRandom
, it can be used as is. Otherwise it has to be incremented by one, so that the lastRandom
has been skipped.
Test to compare code:
