Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++ rand()

Started by atomic_west Mar 6, 2005 at 4:41 PM 13 replies 219.2k views
Original Post
atomic_west
atomic_west
this ones got me funny im learning c++ from a book and the example uses rand() to pick a number to for you t guess but the number is the same every time the program is run here is the source is the book just wrong or am i typing somthing wrong and not seeing it // Magic Number Program. #include #include using namespace std; int main() { int magic; // magic number int guess; // users guess magic = rand(); // get magic number for user to guess cout << "Enter your guess: "; cin >> guess; if(guess == magic) cout << "\n ***right***"; else cout << "You guessed the wrong number sorry \n" << magic <<"\n"; system("pause"); }
Mercury
Mercury
Didn't your parents ever tell you to seed your rands? [smile]
Try this before calling rand():

srand( (unsigned)time( NULL ) );
Trap
Trap
Put srand(time(0)); at the beginnig of your main.

srand sets the start value of rand. Without using srand you always get the default start value.
Dim_Yimma_H
Dim_Yimma_H
You need to initialize the random number generator with a number. If you use the current time to initialize then the random number sequence you get by calling rand() will depend on which time you run the program.

Like this:

#include
#include //time functions

//in your main function do this once
srand(time(0));

//then call rand and the result will depend on the time srand was called

\Jimmy H

edit: me too slow
atomic_west
atomic_west
ok thanks but now how do i get a specific range in the values?? like 1-100
Dim_Yimma_H
Dim_Yimma_H
rand() % 100 + 1

edit: rand() returns a random int (anything that fits in an int) so if you divide by 100 and get the rest it will be between 0 and 99 (add 1 to get 1 - 100).
atomic_west
atomic_west
does that work on any range of numbers say 1-10 or 1-15???
Oluseyi
Oluseyi
rand is a pseudorandom number generator (PRNG). This means that it generates a predictable sequence of numbers according to a complex formula based on the seed value. As you've been shown, you call srand to set the seed (IIRC, it defaults to 1). By saving and restoring your seeds, you can regenerate the same sequence of numbers, which can be useful in the design and implementation of, say, a replay system in your game.

To provide true randomness, however, many people seed rand with the current time, the logic being that the time at which the user will run the program, measured in milliseconds, is about as random as you can get.

Be aware that the Standard Library implementation of rand isn't the best of PRNGs. For instance, the low-order bits of the return value of rand are less random than the high-order bits, which is why using the modulo operator (%) with rand is typically discouraged. These considerations are not necessarily pertinent to your current use, but are good to keep in mind for the future.
envy3d
envy3d
Yes, it does.
mumpo
mumpo
For the range a to b, inclusive, use this:
rand()%((b-a)+1)+a

In other words, the answer to your question is yes, but ONLY if the lower bound is one. Otherwise, you must use the more complicated forumla I provided.
Matt Apple
Matt Apple
# include <iostream># include <cstdlib># include <ctime>using namespace std;int random(int,int);int main(){        srand((unsigned int)time(NULL));        int randInt;        randInt = random(1,6);        cout << randInt << endl;        return 0;}int random(int min, int max){		return (int)((max - min) * rand()/(float)RAND_MAX + min);}


Here is a little widget I use for random numbers. Returns a random integer within a customizable range. Just send the upper and lower bounds as arguments.
MikHaven
MikHaven
Quote:
Original post by Matt Apple
*** Source Snippet Removed ***

Here is a little widget I use for random numbers. Returns a random integer within a customizable range. Just send the upper and lower bounds as arguments.


# include
# include
# include
using namespace std;

int random(int,int);

int main()
{
int randInt = 0;
randInt = random(1,6);
cout << randInt << endl;
return 0;
}

int random(int min, int max)
{
srand((unsigned int)time(NULL));
return (int)((max - min) * rand()/(float)RAND_MAX + min);
}

I'm no code genious but shouldn't you really store your srand inside the 'widget' so you don't seperate out the code from the logic too much, another thing is I love the declare and store operations, but here I've left it 0 just to be sure.

int randInt = randInt = random(1,6);

MikHaven

I know it was lame, but I was just bored. Umm Honest! OK a little code happy as well.
Doc
Doc
Quote:
Original post by Oluseyi
To provide true randomness, however, many people seed rand with the current time, the logic being that the time at which the user will run the program, measured in milliseconds, is about as random as you can get.


The word "random" in the description of time here is probably not the best word to use. For example, it isn't random in the sense that you know for (almost) certain that the next time the user runs the program the time will be later than previously. True, you can't predict how much later, but I still wouldn't call it random. Constantly changing might be a better term. All you need to get a different random series is to start with a different seed, so a constantly changing seed, like time, is all you need.

Another point, if the user runs the program more than once within the precision of whatever timer you use (for 'time' it's one second), you'll get the same seed and thus the same sequence. Someone with that problem started a thread a while ago...
Matt Apple
Matt Apple
Quote:
Original post by MikHaven
I'm no code genious but shouldn't you really store your srand inside the 'widget' so you don't seperate out the code from the logic too much


The problem with that is you really only want to seed your random number generator once(and doing it your way would seed it once every time random() is called. You don't want to seed your number inside a tight loop or you end up getting the same number over and over.

Compare the two following programs...

// This program will return the same number 10 times. Obviously that won't do.# include <iostream># include <cstdlib># include <ctime>using namespace std;int random(int,int);int main(){   int randInt = 0;   for (int x = 0; x < 10; x++)   {       randInt = random(1,6);       cout << randInt << endl;   }   return 0;}int random(int min, int max){     srand((unsigned int)time(NULL));    return (int)((max - min) * rand()/(float)RAND_MAX + min);}



// This program will produce different numbers. This is much better!# include <iostream># include <cstdlib># include <ctime>using namespace std;int random(int,int);int main(){   int randInt = 0;   srand((unsigned int)time(NULL));   for (int x = 0; x < 10; x++)   {       randInt = random(1,6);       cout << randInt << endl;   }   return 0;}int random(int min, int max){     return (int)((max - min) * rand()/(float)RAND_MAX + min);}


The lesson is: Never seed an RNG inside of a tight loop
Because it seeds based on time, reseeding inside of tight loop can cause multiple iterations to receive the same seed and consequently to output the same result.
And because you might call random() inside a tight loop that is why srand should be broken out and placed somewhere else. IMO.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.