user1185827
user1185827

Reputation: 33

Dice Rolling Program generates the same sequence of random numbers on every run

I wrote a program that rolls a die with a user-specified number of sides. The problem is, it's too predictable.

I'm using the CodeBlocks IDE, and the compiler is GCC. The program compiles nicely as both debug and release builds, but no matter what build option I choose, the executable will return the same values every time it's run. I can't have this, because its intended use is as a tabletop RPG tool, and it would be relatively easy for a smart player to cheat if they knew the pattern by which the dice would roll.

What is the easiest way to fix this problem?

Here's the source:

#include <iostream>     /* for input and output */
#include <cstdlib>      /* for random numbers */

using namespace std;

void rolldie() {
    cout << "How many sides to the die?" << endl << "D";
    int die;
    cin >> die;
    int roll = rand() % die +1;
    cout << endl << "The die rolled " << roll << endl << endl <<  "Roll another? (Y for yes, anything else for no; Capitalization counts) ";
}

int main() {
    rolldie();
    char again;
    cin >> again;
    while (again == 89) {
        rolldie();
        cin >> again;
    }
    return 0;
}

Upvotes: 2

Views: 4299

Answers (4)

KeithS
KeithS

Reputation: 71565

Well, first, CStdLib.Rand is not a great PRNG. However I don't know C++ well enough to know what's better in the C++ world; I would look at PRNGs recommended for cryptography. This one should work well enough for most non-security purposes.

More importantly, you haven't "seeded" the PRNG. This does not happen automatically as it is with certain other languages' built-in PRNGs like .NET's. If it's not seeded, then the seed is always constant (probably zero) and so the stream of numbers produced by the PRNG algorithm will always be the same. The most common seed would be based on the current time (preferably at "ticks" resolution so it's hard to guess exactly what fraction of a millisecond was retrieved by the call); other good sources of seed data include the position of the mouse cursor, the last-accessed address of RAM or the HDD, or truly random data available from an attached device (servers for online casinos often have true RNG devices that provide actually random environmental data that can be used to seed a PRNG).

Upvotes: 2

Kerr
Kerr

Reputation: 431

Simple answer:

You want to seed your random number generator each time with input from some source, be it the system (like the time), user, a file, or so on.

Detailed answer:

The default random number generator rand() is very mediocre for most things, but see this for a more detailed answer about rand: What's the Right Way to use the rand() Function in C++?

My recommendation:

My company works with random numbers that are required to be unpredictable on a daily basis and they use a variation of the Mersenne Twister algorithm and as for use in a game you'll find its performance more than adequate.

As an added bonus, it has been implemented in C and C++ in various forms and so integrating it into any project is very simple.

For example: http://www-personal.umich.edu/~wagnerr/MersenneTwister.html

or: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/

Upvotes: 0

Cdaragorn
Cdaragorn

Reputation: 344

Go to http://www.boost.org and get their random number generator library. It's the best random generator I've seen, particularly for c++ where it's really hard to find a decent one anywhere.

They have a TON of really awesome libraries for all sorts of things in c++, so I highly recommend browsing through them, but this should solve the problems you're having of the output being too predictable. Just make sure you read the instructions for how to use it and properly seed the generator first.

As far as what to use for the seed to a random generator, a common one to use in c++ is time(NULL) (found in time.h or ctime). This just returns a number representing the current time in seconds since Jan 1, 1970. Since it will return a different value every time the program is run, it's useful for simpler random numbers, and if you combine that with boost's random generator your output should look good.

Upvotes: 2

Carl Norum
Carl Norum

Reputation: 224854

You didn't seed your random number generator. I'm not going to download your zip file, but since you're using MinGW, I guess you probably want to look into srandom(3) or srand(3).

Upvotes: 8

Related Questions