SFML community forums
General => Feature requests => Topic started by: Walker on April 29, 2011, 11:43:03 am
-
Greetings! I just thought I'd put it out there that the Randomizer class could be improved. I'm not suggesting a more complex PRNG but suggesting to move away from the standard rand() and srand() functions and implement a similar (or the same) one.
The problem with the current system is that there is only one source for random numbers. Being able to create multiple objects of a Randomizer class suggests, to me, that each instance would be a unique source of numbers. Having a single source can also create logical errors as well as cause problems with threading. Finally, and I'm not sure what GLIBC or other libs/compilers use currently, but by implementing the algorithm in SFML, random number generation should be consistent across platforms.
An example:
A game where a system critical to your replay feature uses the PRNG. The game's audio system also accesses the PRNG to choose sound effects. The user tries to watch a replay but has sound disabled - even with the same seed, without the audio system active, the other system is going to get a different series of numbers than it did when the replay was recorded (with audio on).
Maybe not the best example, but I hope you see my point.
This is basically the implementation in VC9:
return( ((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff );
Whether or not you use this specific one doesn't matter - similarly simple ones are readily available. It's a multiply with carry type PRNG, for reference.
One more thing! :lol: I have to recommend moving away from using modulo to get random numbers in range - it hurts distribution. The exact "trick" escapes at the moment but it's better to start with math rand (0.0 - 1.0) and go up from there. EDIT: Just realised your float version of Random pretty much does this. I would adapt that for the integer version too.
Thanks for reading!
-
Thanks for your feedback.
After reading your post, which contains many relevant points, my conclusion is that... sf::Randomizer should be removed from SFML.
There's a standard API for random numbers, which is simple enough to use, and for more specific needs there are other APIs available (boost, next C++ standard).
-
Not quite the response I expected :lol:, but I suppose it makes sense. Certainly with C++0x having this functionality makes including it in any library a bit redundant.
-
I have to recommend moving away from using modulo to get random numbers in range - it hurts distribution. The exact "trick" escapes at the moment but it's better to start with math rand (0.0 - 1.0) and go up from there.
Blech.
Using modulo is no worse for distribution than any other [linear] approach. Scaling 0.0 - 1.0 up to the desired range is no better.
The end result of either approach is you're taking X possible outputs and scaling them down to Y outputs. Any way you slice it, there's a direct approach to where 1 random number gets converted to 1 output number. So unless Y is a perfect multiple of X, there will always be distribution issues no matter which approach you use.
The only way to solve distribution problems (that I know of) would be to "reroll" on certain outcomes. Like if you can get ideal distribution with [0..8) and you want [0..6), then have outputs of 6 and 7 be "rerolled" until you get [0..6)
EDIT: but of course even that can have adverse effects on distribution if you're using the same RNG sequence for multiple things.
EDIT 2:
Actually, the approach where you scale up from [0..1) approach would be worse for distribution than using modulo if you're using floats, because it makes the pool size (X) smaller.
Though I suppose if you use doubles instead of floats it works out to the same.
-
There's a standard API for random numbers, which is simple enough to use, and for more specific needs there are other APIs available (boost, next C++ standard).
Of course.
However, don't forget the S in SFML. In one line, we can have a random number, easilier than any other ways.
The only necessary improvement is to have the same result on all platform, and wich is not compiler-dependent.
Furthermore, it doesn't burdening SFML :wink:
-
I already removed sf::Randomizer.
However, don't forget the S in SFML. In one line, we can have a random number, easilier than any other ways.
With the standard library too.