Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: A better sf::Randomizer  (Read 6632 times)

0 Members and 2 Guests are viewing this topic.

Walker

  • Full Member
  • ***
  • Posts: 181
    • View Profile
A better sf::Randomizer
« 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!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
A better sf::Randomizer
« Reply #1 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).
Laurent Gomila - SFML developer

Walker

  • Full Member
  • ***
  • Posts: 181
    • View Profile
A better sf::Randomizer
« Reply #2 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.

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
A better sf::Randomizer
« Reply #3 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.

The DarK'

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
A better sf::Randomizer
« Reply #4 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:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
A better sf::Randomizer
« Reply #5 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.
Laurent Gomila - SFML developer