6

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?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Michael Ochs
  • 2,846
  • 3
  • 27
  • 33
  • What do you need the random numbers for, specifically? – Jonathan Grynspan Jul 08 '12 at 08:42
  • Excuse my ignorance but what does Deterministic mean? – The Muffin Man Jul 08 '12 at 08:50
  • 3
    @Nick I assume the OP wants to be able to regenerate the same sequence of "random" numbers when providing the same seed value. – Eitan T Jul 08 '12 at 08:51
  • 1
    You say " It doesn't have to be too good. It is used for a game". I pay good money for games and I expect the world! – The Muffin Man Jul 08 '12 at 08:53
  • For clarification: I have everything running in one process. By instance I really mean object instances. So I have several game engine objects and they all should use different random number pools. Also @Nick: I just wanted to point out that I don't use this for crypto stuff, so it doesn't have to be really unpredictable. – Michael Ochs Jul 08 '12 at 12:08
  • 2
    @Nick: Deterministic means if given the same initial settings, it will produce the same result. In other words, it means "not random". In the context of random number generation, this means that the numbers generated *look* random, but can be calculated, given the initial seed. – undecim Feb 15 '13 at 19:14

5 Answers5

7

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.

Community
  • 1
  • 1
Eitan T
  • 32,660
  • 14
  • 72
  • 109
  • 1
    The relevant portion of the documentation being: `"The srand() 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."` – Chris Cooper Jul 08 '12 at 09:16
  • 1
    I think you missed the "it is important, that each instance of the Game Engine has it's own pool of numbers" part of the question. When using rand, the RNG's state is global and if you use rand() anywhere in your program, that will affect all parts of the program (likewise calling srand anywhere in the program will reset the state everywhere in the program). – sepp2k Jul 08 '12 at 10:01
  • 1
    @sepp2k Different game instances = different processes. Isn't that enough? – Eitan T Jul 08 '12 at 10:19
  • @EitanT It sounded to me like he wanted to have multiple instances of the game engine in the same process. Either way he also said "or even other parts of the game", so he clearly wants to be able to use random numbers in some parts of the game without affecting the RNG state of the game engine(s). – sepp2k Jul 08 '12 at 10:26
  • @sepp2k Not sure about "other parts", but I'll add a clarification in my answer now. Thanks for your comment. – Eitan T Jul 08 '12 at 10:30
  • Thanks I have a look at rand_r(), this might be what I am looking for, even though I don't find the man page very clear on what it is doing. – Michael Ochs Jul 08 '12 at 12:10
  • @user653133 Then you should also take a look at [this question](http://stackoverflow.com/questions/3973665/how-do-i-use-rand-r-and-how-do-i-use-it-in-a-thread-safe-way)... – Eitan T Jul 08 '12 at 12:18
3

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.

Christian Stieber
  • 9,954
  • 24
  • 23
2

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…

Wevah
  • 28,182
  • 7
  • 83
  • 72
2

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

Any good PRNG library should be able to do this. GNU Scientific Library provides support for generating random numbers via many diferent algorithms, and from many probability distributions. Each call to gsl_rng_alloc sets up an independent random number generator with its own state, which you can seed using gsl_rng_set. You probably want to use different seeds for different parts of the program, and depending on which PRNG algorithm you use, some particular seeds might not work very well. Copying and pasting a few numbers from random.org is probably a good way of getting seeds.

James
  • 3,191
  • 1
  • 23
  • 39