# Bug in game.rnd.integerInRange

## Recommended Posts

I do not know whether this is the correct place to report a bug. I hope it is.

The function game.rnd.integerInRange() is not correct.

The following code:

var digitos = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (var i = 0 ; i < 10000 ; i++) {
digitos[app.game.rnd.integerInRange(0, 9)]++;
}
console.log(JSON.stringify(digitos));

should get a counter of about 1000 for each digit. The distribution is incorrect (an example):

[560,1073,1090,1118,1158,1105,1067,1172,1117,540]

The first and last value are generated with half the probability of the other values.

The reason is that the function integerInRange uses this statement:

return Math.round(this.realInRange(min, max));

Math.round(this.realInRange(0, 9)) returns the value 0 for values between 0 and 0.4999..., but it returns 1 for values between 0.5 and 1.4999..., hence the double probability.

One possible alternative for the incorrect statement is:

return Math.trunc(this.realInRange(min, max + 1));

-------

Thanks for Phaser. It's great.

##### Share on other sites

The solution I gave is only valid for positive values of 'min' and 'max'. The correct code for positive and negative values of 'min' and 'max' is:

if (min >= 0) {
return Math.trunc(this.realInRange(min, max + 1));
} else {
return min + Math.trunc(this.realInRange(0, max - min + 1));
}

##### Share on other sites

Can't use Math.trunc I'm afraid, it's ES6 experimental only.

##### Share on other sites

That is true. I noticed it when my program failed in different devices. So this is the solution (which is more elegant than the previous one) valid for positive and negative values of 'min' and 'max':

/**
* Returns a random integer between and including min and max.
*
* @method Phaser.RandomDataGenerator#integerInRange
* @param {number} min - The minimum value in the range.
* @param {number} max - The maximum value in the range.
* @return {number} A random number between min and max.
*/

integerInRange: function (min, max) {

return Math.floor(this.realInRange(0, max - min + 1)) + min;
},

##### Share on other sites

• 3 weeks later...

I'd like to add that the suggested formula above (which I see is in the 2.0.4) is vounerable. If "min" is not an int (that it should need to be is not implied in the name of function or in the help), it will not work appropriately due to the final adding of "min".

The "max" is already safe, which makes it extra confusing, I think.

This caused a quite strange error for me today.

To safe that I only see the solution of adding a:

`min = Math.ceil(min);`

above the return line.

##### Share on other sites

Interesting, but do you not think that the method name integerInRange automatically implies you should give it a range of numbers?!

##### Share on other sites

Actually sorry, I see what you mean - if you give min as say 4.5 you don't get an integer back because the above solution just dumps it onto the end of the calculation without checking it. I'll sort that out.

##### Share on other sites

Looking at it I'm sure you can simply move the min value inside the Math.floor already there:

`return Math.floor(this.realInRange(0, max - min + 1) + min);`