Public Group

# Random Number Generator

This topic is 788 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm running to some issues with a random number generator that I am trying to create to test what type of attack an enemy will use (weapon or magic) and whether or not they land a hit with the attack.  What I want it to do is generate a random number number for the type of attack, then generate a separate random number for if the hit lands or not.  What actually happens is it is generating a different number each iteration, but the same number for each item.  So for instance, if the random number is a 6, both attack type and if it hit is a 6, if it's a 7 both are 7, etc.   I'm almost certain the issue is within how I'm using time in conjunction with this, but everything else I've found hasn't been helpful.  I've tried doing one function, but had the same issue and switched to two functions in the hopes that would help, but it didn't and now I'm not quite sure what to try next.

Here is the code I have so far:

// Example program
#include <iostream>
#include <string>
#include <stdlib.h>
#include <ctime>

using namespace std;

int getRandAttack();
int getRandHit();

int main()
{

int randomAttack;
int randomHit;

randomAttack = getRandAttack();
cout<<randomAttack<<endl;  //used to ensure same number isn't given every time

//decides what happens based on what number was given
if (randomAttack <= 5)
{
cout<<"Enemy used a weapon!"<<endl;
}else if (randomAttack > 5)
{
cout<<"Enemy used magic!"<<endl;
}

randomHit = getRandHit();
cout<<randomHit<<endl;  //used to ensure same number isn't given every time

//decides what happens based on what number was given
if (randomHit <= 5)
{
cout<<"The attack missed!";
}else if (randomHit > 5)
{
cout<<"The attack hit!";
}
}

//gets random number to determine enemy attack type
int getRandAttack ()
{
int random;
srand (time(NULL));

random = rand() % 10 + 1;
return random;
}

//gets random number to determine if enemy attack lands a hit
int getRandHit ()
{
int random;
srand (time(NULL));

random = rand() % 10 + 1;
return random;
}

I know there is an easier way to do this that involves classes, but the online compiler I'm messing around with right now doesn't seem to support extra files, so I'm making functions work instead.  Any help and lead in the right direction would be greatly appreciated.

##### Share on other sites
Quote

srand(time(NULL)) should be run exactly once to intialise the PRNG. Do this in Main when the application starts.

##### Share on other sites
53 minutes ago, TheChubu said:

Okay thanks.  I'll give that a try in the morning.

##### Share on other sites

You can also have a counter running and flag that how you like, this works if you need 1 random value at some time.

Edited by the incredible smoker

##### Share on other sites

Using the C++ standard library for generating pseudorandom numbers is easy and less error-prone than most of the alternatives.

#include <random>
#include <iostream>

//gets random number to determine enemy attack type
int getRandAttack ()
{
static std::random_device rd;  // Will be used to obtain a seed for the random number engine.
static std::mt19937 gen(rd()); // Standard Mersenne twister seeded with rd().
static std::uniform_int_distribution<> dist(1, 10);

return dist(gen);
}

//gets random number to determine if enemy attack lands a hit
int getRandHit ()
{
static std::random_device rd;
static std::minstd_rand gen(rd()); // Smaller, faster simple LCG generator (good enough for most uses) seeded with rd().
static std::uniform_int_distribution<> dist(1, 10);

return dist(gen);
}

int main()
{
// same as OP's example
}

I would rather have the generators as class members instead of all the static cruft, but this is a drop-in replacement.

##### Share on other sites
2 hours ago, Bregma said:

Using the C++ standard library for generating pseudorandom numbers is easy and less error-prone than most of the alternatives.


#include <random>
#include <iostream>

//gets random number to determine enemy attack type
int getRandAttack ()
{
static std::random_device rd;  // Will be used to obtain a seed for the random number engine.
static std::mt19937 gen(rd()); // Standard Mersenne twister seeded with rd().
static std::uniform_int_distribution<> dist(1, 10);

return dist(gen);
}

//gets random number to determine if enemy attack lands a hit
int getRandHit ()
{
static std::random_device rd;
static std::minstd_rand gen(rd()); // Smaller, faster simple LCG generator (good enough for most uses) seeded with rd().
static std::uniform_int_distribution<> dist(1, 10);

return dist(gen);
}

int main()
{
// same as OP's example
}

I would rather have the generators as class members instead of all the static cruft, but this is a drop-in replacement.

I would rather do it as a class too, but I was just messing around with some code to get a better hang of the random number generators.  Thank you for the help and I will definitely give this a try and look further into the other features the standard library has.

13 hours ago, swiftcoder said:

Also worth mentioning, C++ developers aren't stuck with rand() these days. The standard library has some nifty alternatives.

I'll have to look into those alternatives.  Thanks for the suggestion!

TheChubu - Thanks for the suggestion!  I tried it out and that worked.  Now I'm going to look into the other suggestions to see if I can make this more reusable and viable in a game!

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 16
• 11
• 24
• 43
• 75