29

My random numbers that output, output in the same sequence every time I run my game. Why is this happening?

I have

#include <cstdlib> 

and am using this to generate the random numbers

randomDiceRollComputer = 1 + rand() % 6;
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
soniccool
  • 5,790
  • 22
  • 60
  • 98

4 Answers4

41

You need to seed your random number generator:

Try putting this at the beginning of the program:

srand ( time(NULL) );

Note that you will need to #include <ctime>.

The idea here is to seed the RNG with a different number each time you launch the program. By using time as the seed, you get a different number each time you launch the program.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • Hmm what exactly does that mean in terms of seeding? – soniccool Oct 13 '11 at 00:24
  • 6
    Basically, RNGs aren't really random. They use a formula to that generates seemingly (pseudo) random numbers. And as such they need a "starting point" to begin generating a sequence. If you don't seed, it will use the same default seed and generate the same sequence every time. – Mysticial Oct 13 '11 at 00:27
  • 5
    For better results, call `rand` once after the `srand` and throw away the return value. It turns out that similar seeds generate a similar first value, but it diverges rapidly. – Mark Ransom Oct 13 '11 at 00:51
  • @MarkRansom: I wasn't aware of that! I guess I learned something today. :) – Mysticial Oct 13 '11 at 00:57
  • 1
    But note that, on most implementations, `time(NULL)` will give you the same value if you run the program twice within a second. This may or may not be a problem, depending on the application. – Keith Thompson Oct 13 '11 at 00:58
  • 1
    @KeithThompson: Correct. When it's a problem for me, I seed with `rdtsc`. But that's a different story... – Mysticial Oct 13 '11 at 00:59
  • 2
    @Mysticial: If your needs are serious enough that `srand(time(NULL))` isn't good enough, it's likely that `rand()` isn't good enough. – Keith Thompson Oct 13 '11 at 01:14
  • @KeithThompson: It depends. I answered a question on this here: http://stackoverflow.com/questions/7617587/is-there-an-alternative-to-using-time-to-seed-a-random-number-generation – Mysticial Oct 13 '11 at 01:18
9

You need to give the randum number generator a seed. This can be done by taking the current time, as this is hopefully some kind of random.

#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int  r;
    srand(time(0));
    r = rand();
    return 0;
} 
tune2fs
  • 7,605
  • 5
  • 41
  • 57
4

The rand() function is specifically required to produce the same sequence of numbers when seeded with a given seed (by calling srand()); each possible seed value specifies a sequence. And if you never call srand(), you get the same sequence you would have gotten by calling srand(1) before any call to rand().

(This doesn't apply across different C or C++ implementations.)

This can be useful for testing purposes. If there's a bug in your program, for example, you can reproduce it by re-running it with the same seed, guaranteeing that (barring other unpredictable behaviors) you'll get the same sequence of pseudo-random numbers.

Calling srand(time(NULL)) is the usual recommended way to get more or less unpredictable pseudo-random numbers. But it's not perfect. If your program runs twice within the same second, you'll probably get the same sequence, because time() (typically) has a resolution of 1 second. And typical `rand() implementations are not good enough for cryptographic use; it's too easy for an attacker to guess what numbers you're going to get.

There are a number of other random number implementations. Linux systems have two pseudo-devices, /dev/random and /dev/urandom, from which you can read reasonably high-quality pseudo-random byte values. Some systems might have functions like random(), drand48(), and so forth. And there are numerous algorithms; I've heard good things about the Mersenne Twister.

For something like a game, where you don't expect or care about players trying to cheat, srand(time(NULL)) and rand() is probably good enough. For more serious purposes, you should get advice from someone who knows more about this stuff than I do.

Section 13 of the comp.lang.c FAQ has some very good information about pseudo-random number generation.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
1

Pseudorandom number generators take a starting number, or seed, and then generate the next number in the sequence from this. That's why they're called pseudorandom, because if they always use the same starting value, they will generate the same sequence of numbers like the C standard lib generator does. This can be fixed by giving the generator a starting value that will change the next time the program is run like the current time.

Anyway, the code you're looking for like others have said is:

srand(time(0)); //Seed the generator, give it a starting value
jgon
  • 698
  • 4
  • 11
  • No, they're called pseudorandom because they're not truly random in the mathematical sense, only an approximation. A PRNG that generates distinct numbers each time it's run is still pseudorandom. – Keith Thompson Oct 13 '11 at 00:56
  • @KeithThompson I know, I meant that that's why this specific type of PRNG is a PRNG. More generally a PRNG is known as pseudorandom, because it uses a deterministic algorithm to find each value of the sequence, correct? – jgon Oct 13 '11 at 01:29