Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deterministic random number generator with context?

I am looking for a seeded random number generator that creates a pool of numbers as a context. It doesn't have to be too good. It is used for a game, but it is important, that each instance of the Game Engine has its own pool of numbers, so that different game instances or even other parts of the game that use random numbers don't break the deterministic character of the generated numbers.

Currently I am using rand() which obviously doesn't have this feature.

Are there any c or objective-c generators that are capable of doing what I want?

like image 298
Michael Ochs Avatar asked Jul 08 '12 08:07

Michael Ochs


4 Answers

Use srand to set the seed, and then use rand():

unsigned int seed = 10;  /* Choose an arbitrary value for the seed */
int r;

srand(seed);             /* Set the seed                           */
r = rand();              /* Generate a random number               */

The man page explicitly states that the sequence of pseudo-random numbers can be repeatable (and hence it is deterministic):

Thesrand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value.


Edit (clarification):
Note that the man page states that srand() is niether reentrant nor thread-safe.
I assumed that by "different game instances" you meant different processes, in which case it is okay to use it.
However, if you plan on changing seeds within the same process, you won't get the functionality that you want. In this case I recommend using rand_r() instead. Take a look at this question for reference.

like image 71
Eitan T Avatar answered Oct 20 '22 16:10

Eitan T


It seems you don't need a "context" (whatever that may mean); instead you are looking for a PRNG implementation where you can save and restore the current state. This is actually possible with any PRNG implementation that you implement yourself (since you can always save the state), whereas library functions may or may not give you access to the state.

For Linux and MacOS, they actually added a rand_r in addition to rand -- this is documented as a thread safe, reentrant version of rand, but the "magic" behind that is simply that it takes a pointer to the current state instead of keeping it in a static variable. Other random number functions like the drand48 family seem to have versions with additional parameters as well, although I would have to do more reading to find out whether it can be used to store the state.

Either way, if you 'google' or 'wikipedia' for a random number generator to implement yourself, making the 'current state' an explicit parameter will be trivial.

like image 20
Christian Stieber Avatar answered Oct 20 '22 17:10

Christian Stieber


You might be able to use random() and setstate(). I haven't used setstate() myself, but the manpage seems to indicate it might do what you want…

like image 2
Wevah Avatar answered Oct 20 '22 18:10

Wevah


The 'obvious' PRNG to use is the drand48() family of functions. These allow you to provide 48 bits of state, and even allow you to set the multiplier and constant used in the calculations.

like image 2
Jonathan Leffler Avatar answered Oct 20 '22 18:10

Jonathan Leffler