SFML community forums

General => Feature requests => Topic started by: Walker on April 29, 2011, 11:43:03 am

Title: A better sf::Randomizer
Post 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:
Code: [Select]
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!
Title: A better sf::Randomizer
Post by: Laurent on April 29, 2011, 11:52:23 am
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).
Title: A better sf::Randomizer
Post by: Walker on May 02, 2011, 04:14:35 am
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.
Title: A better sf::Randomizer
Post by: Disch on May 02, 2011, 04:37:40 am
Quote
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.
Title: A better sf::Randomizer
Post by: The DarK' on May 13, 2011, 11:44:30 pm
Quote from: "Laurent"
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:
Title: A better sf::Randomizer
Post by: Laurent on May 14, 2011, 11:42:50 am
I already removed sf::Randomizer.

Quote
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.