Random generator for guess game - c++

I've been searching for a better solution than my own and I haven't really been able to find one that I understand or that works for me.
I have made the simple game where the computer randomly generates a number which you then guess a number and if it is higher the computer says higher and so on..
The problem is my randomly generated number, after looking up alot of information regarding the <random>, uniform_int_distribution and default_random_engine. I have found out that the computer generates a random number, but if you run the program again the same random number will be generated.
My solution:
uniform_int_distribution<unsigned> u(0,100); // code to randomly generate numbers between 0 and 100
default_random_engine e; // code to randomly generate numbers
size_t userInput; // User input to find out where to look in the vector
vector<int> randomNumbers; //vector to hold the random numbers
unsigned start = 0, ending = 101, cnt = 0; // used in the game not important right now
cout << "Please enter a number between 1 and 1000 for randomness" << endl;
cin >> userInput;
for(size_t i = 0; i < 1000; ++i){ //for loop to push numbers into the vector
randomNumbers.push_back(u(e));
}
unsigned guess = randomNumbers[userInput]; // finally the number that the user will have to guess in the game
My solution right now is to use a vector where I push alot of randomly generated numbers in then ask the user to type a number which then the computer uses for the game. But there should be a better way of doing this. And my question is therefore
Is there a better way to randomly generate numbers to use in the game?

Either use std::random_device in place of std::default_random_engine, or else think of a way to provide a different number to the engine each time it is run.
This number is called a "seed" and can be passed as an optional parameter to the constructor. Since std::default_random_engine is implementation-specific, and different engines do different things about seeding, you generally want to choose a specific engine if you're providing a seed. A deterministic pseudo-random number generator will produce the same sequence of outputs for any given seed, so you want to use a different seed each time.
For no-security uses like a guessing game, the most "obvious" thing to use as a seed is the current time. Generally speaking this is different each time the program is run, although obviously if you can run the program twice in less than the granularity of the clock then that's not the case. So using the time to seed your random engine is pretty limited but will do the job for a toy program.

That's because your random number is actually what we call a pseudorandom number generator
It's just a machine that given a starting number generates a large list of seemingly random numbers. As you don't provide a starting number, the generated list of random numbers is thus always the same. One easy way to fix this is to use the current time as a starting value or 'seed', which is an argument of the constructor of std::default_random_engine.
You can also use your machines real random number generator std::random_device as a replacement for std::default_random_engine

Why not simply:
#include <ctime> // for time()
#include <cstdlib> // for srand()
srand(time(NULL)); // Initializes the rand() function
int randomNumber = rand()%100; // Random number between 0 and 99.
What this does is the rand() seed is set at the current time, meaning that every execution of the program will have a different seed for rand().
Still just pseudo-random solution, though suitable for your purposes.

Related

Random number generator repeats every time?

I'm trying to find a random number generator that will give me a single random number each time I run it. I have spent a week trying dozens of different ones, both from this site and others. Every time I run it, it gives me the same number! The only time it changes is if I change the range, and then it just gives me the new number over and over.
I am running Code::Blocks ver. 16.01 on Windows 7. Can anyone help?? I'm at my wits' end!
This code gives me a decently ramdom string of numbers, but still the same string each time!
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 eng(rd()); std::uniform_int_distribution<> distr(0, 10);
for(int n=0; n<100; ++n)
std::cout << distr(eng) << '\t';
}
I have tried the code on my compiler app on my phone as well.
Every pseudo random number generator will return the same sequence of numbers for the same initial seed value.
What you want to do is to use a different seed every time you run the program. Otherwise you'll just be using the same default seed every time and get the same values.
Picking good seeds is not as easy as you might think. Using the output from time(nullptr) for example still gives the same results if two copies of the program run within the same second. Using the value of getpid() is also bad since pid values wrap and thus sometimes you'll get the same value for different runs. Luckily you have other options. std::seed_seq lets you combine multiple bad sources and returns a good (or rather, pretty good) seed value you can use. There is also std::random_device which (on all sane implementations) returns raw entropy - perfect for seeding a pseudo random generator (or you can just use it directly if it is fast enough for your purpose) or you can combine it with std::seed_seq and the bad sources to seed a generator if you are worried it might be implemented as a prng on your implementation.
I would advice you to read this page: http://en.cppreference.com/w/cpp/numeric/random for an overview of how to deal with random number generation in modern C++.
The standard allows std::random_device to be implemented in terms of a pseudo-random number generator if there is no real random source on the system.
You may need to find a different entropy source, such as the time, or user touch co-ordinates.

Random number generator - why seed every time

I am relative new to c and c++. In java, the language I am used to program in, its very easy to implement random number generation. Just call the the static random-method from a class called Math.
int face = ((int)(Math.random() * 6) + 1);
simulates a dice-throw ...
In c and c++ you have to "seed the random number generator" , by calling the srand-function
srand ( time(NULL) );
What is the point of doing this - I mean is there any advantage of having to seed the random number generator every time the code is run?
Given the same seed, a pseudo random number generator will produce the same sequence every time. So it comes down to whether you want a different sequence of pseudo random numbers each time you run, or not.
It really depends on your needs. There are times when you want to repeat a sequence. And times when you do not. You need to understand the needs of each specific application.
One thing you must never do is seed repeatedly during generation of a single sequence. Doing so very likely will destroy the distribution of your sequence.
What's usually called a random number generator is actually a pseudo-random number generator. This typically means that you can generate the same random sequence if you provide the "key" to that sequence, referred to as the "seed". This is very useful when you wish to test your algorithm that is based on randomization, and you need to ensure repeatable results.
If you do not "seed" your Random number generator, it is seeded with some (usually based on system time) random number by default, and therefore produces the different sequence every time that you run your program.
If you don't seed the generator, it will have the same seed every time you run your program, and the random number sequence will be the same each time.
Also note that you only should to seed the generator once, at the beginning of the program.
The advantage is that you can repeat a random number sequence by supplying the same seed.
The game Elite used this to store an entire world, consisting of thousands of stars, as a single number.
To generate the exact same world a second time, the just supplied the same seed.
The seed is needed for pseudo random number generator to generate different random number sequence from previous ones (not always). If you do not want the repeated sequence then you need to seed the pseudo random number generator.
Try these codes and see the difference.
Without seed:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%d", rand()%6 + 1);
}
With seed:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL));
printf("%d", rand()%6 + 1);
}
The random number generator is not truly random: say you seed it with 12 and make 100 random numbers, repeat the process and seed it with 12 again and make another 100 random numbers, they will be the same.
I have attached a small sample of 2 runs at 20 entries each with the seed of 12 to illustrate, immediately after the code which created them:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
srand(12);
for (int i =0;i<100; i++)
{
cout << rand() << endl;
}
return 0;
}
To avoid such repetition it is commonplace to use a more unique value, and as the time is always changing, and the chances of a two programs generating random sequences at exactly the same time are slim (especially when at the millisecond level), one can reasonably safely use time as an almost unique seed.
Requirements: seeding only need take place once per unique random sequence you need to generate.
However, there is an unexpected up-/down-side to this:
if the exact time is known of when the first sequence is generated then the exact sequence can be re-generated in the future by entering the seed value manually, causing the random number generator to step through its process in the same fashion as before (this is an upside for storing random sequences, and a downside for preserving their randomness).
In C/C++, a dice roll would be simulated like this:
int face = (rand() % 6) + 1);
^
|___________ Modulo operator
The % 6 limits the random number to 0 through 5 and the + 1 is made to offset the limit, so it becomes 1 through 6.

generate 1000 random card deck shuffles at once c++

I'm basically trying to build a computer simulation of a casino game idea that uses a standard deck of 52 cards.
I would like to run 1000 games at once.
I've used srand(time(NULL)) before, but I dont think it's possible to output 1000 different random number sequences at one time with this, is there? My perception is that since all the numbers are generated at the same time, that they will all be the same.
Is there a way to use the first generated random number to seed 1000 new 52 number sequences?
Thanks
Yes, you can have your first random number generator (seeded with time(NULL)) output 1000 random numbers, each of which can be used as a seed for 1000 separate random number generators.
My perception is that since all the numbers are generated at the same
time, that they will all be the same
They are not generated at the same time. I presume you are using a for loop? Each iteration is not
at the same time".
Did you even test this theory?
for i = 1 to 1000 do
{
print <time to ms resolution>
print <random number>
}
Seeding with the same number will always lead to the same sequence of pseudo-random numbers. As long as you don't re-seed with the same seed in between iterations, the (sub)sequences are not going to be the same.
try seeding the rand() function with srand(time(NULL)*getpid()). PID of the process that you are invoking a 1000 times should be system dependent and has a good chance of being different from one another.
If you are using threads for different games, use threadID instead of getpid().
If you want you can pre-generate all random numbers at once and use them later:
int random_numbers[1000];
for (i = 0; i < 1000; i++) {
srand(time(NULL)*(i+1));
random_numbers[i] = rand();
}

Same random numbers every time I run the program

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;
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.
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;
}
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.
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

C++: seeding random number generator outside of main()

I was creating a simple program that simulates a coin toss for my class. (Actually, class is over this term and i'm just working through the rest of the projects that weren't required). It involves the creating and calling a function that generates a random number between 1 and 2. Originally, I tried to seed the random number generator within the function that would be using it (coinToss); however, it did not produce a random number. Each time the program was run it was the same number as though I had only used
rand()
instead of
unsigned seed = time(0);
srand(seed);
rand();
Yet, when i moved the above within
int main()
it worked fine.
My question is 1)why did it not work when setup within the function that called it and (2) how does rand()
have access to what was done by srand() if they do not both occur in the same function?
Obviously, i'm a beginner so please forgive me if i didn't formulate the question correctly. Also, my book has only briefly touched on rand() and srand() so that's all i really know.
thanks for any help!
Pertinent code:
First attempt that didn't work:
int main()
{
//...........
coinToss();
//...........
}
int coinToss()
{
unsigned seed = time(0);
srand(seed);
return 1 + rand() % 2;
}
Second attempt which did work:
int main()
{
unsigned seed = time(0);
srand(seed);
coinToss();
}
int coinToss()
{
return 1 + rand() % 2;
}
You probably only want to seed the random number generator once. rand() returns the next pseudo-random number from it's internal generator. Every time you call rand() you will get the next number from the internal generator.
srand() however sets the initial conditions of the random number generator. You can think of it as setting the 'starting-out point' for the internal random number generator (in reality it's a lot more complicated than that, but it's a useful cognitive model to follow).
So, you should be calling srand(time(0)) exactly once in your application - somewhere near the beginning. After that, you can call rand() as many times as you want!
However
To answer your actual question - the first version doesn't work because time() returns the number of seconds since the epoch. So If you call coinToss() several times in a second (say, if you wanted to simulate 100 coin tosses), then you'd be constantly seeding the random number generator with the same number, thereby resetting it's internal state (and thus the next number you get) every time.
Anyway - using time() as a seed to srand() is somewhat crappy for this very reason - time() doesn't chage very often, and worse, it's predictable. If you know the current time, you can work out what rand() will return. The internet has many, many examples of better srand() seeds.
Pseudo-random number generators (like rand) work by taking a single starting number (the seed) and performing a numeric transformation on it each time you request a new number. You want to seed the generator just once, or it will continually get reset, which is not what you want.
As you discovered, you should just call srand just once in main. Also note that a number of rand implementations have pretty short cycles on the low 4 bits or so. In practice this means you might get an easily predictable repeating cycle of numbers You might want to shift the return from rand right by 4-8 bits before you take the % 2.
EDIT: The call would look something like:
return 1 + (rand() >> 6) % 2;
Seed only once per program, not every time you call coinToss()
To expand on Mark B's answer: It is not so much that the random number generator is reset as it sets a new variable to be used in calculating random numbers. However your program doesn't do that much work between calls to srand. Therefore every time you call srand(time(0)) it is using the same seed, so you are resetting the internal state of the random number generator . If you put a sleep in there so that time(0) changed you would not get the same number every time.
As for how data passes from srand to rand, it is fairly simple, a global variable is used. All names that start with an underscore and a capital letter or two underscores are reserved for variables used by your compiler. More than likely this variable has been declared static so it isn't visible outside of the translation unit(aka the library file that contains your compiler's standard library.) This is done so that #define STUFF 5 doesn't break your standard library.
for simple simulations, you must not change the seed at all during the simulation. Your simulation will be "worse" in that case.
To understand this, you should see pseudo random sequences as a big wheel of fortune. When you change the seed, it is like you change the position, and then, each call to rand will give you a different number. If you roll again, it will be more probable finding yourself repeating numbers.