Jump to content
  • Advertisement
ICanC

C++ Random number issue

Recommended Posts

I'm struggling to get random numbers, in the below code, If I take out the time seed, I get different random numbers each roll, however they are the same on each play through.

If I leave the time seed in, the rolls are always 1 and 1. Please can someone advise what I am doing wrong? I've tried making the game sleep a few seconds to change the results of time time seed call

void dicegame::battle(character *a, character *b)
{
    int rollone = this->roll(); int rolltwo = this->roll(); int total1 = rollone+rolltwo; Sleep(5000);

    int rollone2 = this->roll(); int rolltwo2 = this->roll(); int total2 = rollone2+rolltwo2;  Sleep(5000);
}

int dicegame::roll()
{
    static std::uniform_int_distribution<int> u(1, 6);
    static std::default_random_engine e;
    e.seed(time(0));
    int roll = (u(e));
    return roll;
}

 

 

Share this post


Link to post
Share on other sites
Advertisement
e.seed(time(0));

Try to comment out this line - it's reinitializing seed.

 
Quote

 

Seed engine

Re-initializes the internal state value:

 

 

and move `e` and `u` init code somewhere else.

Edited by edin-m

Share this post


Link to post
Share on other sites

I'm guessing what you want is this: 

static std::uniform_int_distribution<int> u(1, 6);
// Seed the engine only *once*
static std::default_random_engine e(time(0));
int roll = (u(e));
return roll;

ie, you want to initialize the engine with a seed **once**. And let it generate random values from there.

Might be wrong syntax for that though, I don't know if std::default_random_engine has a constructor where you can pass it a seed value. Someone with more C++ experience can tell you how to do that properly. EDIT: Nvm, it's fine.

The seed in that case will be the current time of the system. So it should vary enough across playthroughs to be useful.

If you take out the seed, what happens is that the generator gets initialized with a default seed every single time, and these random number generators are deterministic. ie, if you seed it with the same number, they'll produce the same sequence of values. That's pretty useful because it allows you to reproduce them if you keep around the seed that originated them.

Edited by TheChubu

Share this post


Link to post
Share on other sites

Just to be clear: a pseudorandom number generator (PRNG) is a mathematical operation that generates a series of numbers by applying a function to a state vector, replacing the state vector with new value each time.  The state vector needs to be initialized to something at the start of the sequence (a process called seeding), and if you manually change the state on each iteration you're messing up the sequence and you're going to have problems.

The size of the state vector for the classic std::minstd_rand0 is 32 bits.  The size of the state vector for std::mt19937 is 19968 bits.  The std::default_random_engine is likely one of those two PRNGs (I have not seen a standard library use anything else, but it's possible).  If you seed std::mt19937 with an unsigned int (which is what you would be doing if you use time(0) and your library has implemented std::default_random_engine using std::mt19937), then it actually uses that seed value to initialize a std::minstd_rand0 engine to generate the seed vector.  Fun facts.

I don't recommend using time(0) as a seed.  Use std::random_device instead, at least on desktop systems.

Share this post


Link to post
Share on other sites
Posted (edited)

I personally use the following to generate random numbers.

 

#include <iostream>
#include <random>

int main()
{
	std::random_device rd;
	std::mt19937 mt(rd());

	int randomNumber = 0;

	for (int a = 0; a < 10; a++)
	{
		std::uniform_int_distribution<unsigned> u(1, 100);
		randomNumber = u(mt);
		std::cout << randomNumber << std::endl;
	}

	std::cin.get();

	return 0;
}

 

This will run a for loop 10 times, generating a number randomly between 1 and 100.

Avoid using time() like @Bregma stated. Use random_device.

Edited by Rutin

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!