Dice simulator for Pig, c++ - c++

I'm actually learning C++ language and I'm doing the Pig Game, which needs a dice to play, my problem is that my dice is always rolling the same numbers , no matter how many times I close CodeBlocks or re-run the program. I would like to say as well, that I already used a variable like: dice=rand() % 6 + 1, but I'm currently using:
int roll() {
return rand() % 6 + 1 ;
}
which I consider better(idk why).
Any explanation of why this is giving me the same rolls over and over? Thank you very much for answers ^^

At least in C, before using rand you should call srand(time(NULL));.

C style
std::srand(std::time(NULL)); // calling it once at the start of program is enough
//later in code
std::rand() % 6 + 1;
C++ Style Source
std::default_random_engine generator; // there are many random engines in <random> header
std::uniform_int_distribution<int> distribution(1,6);
int dice_roll = distribution(generator); // generates number in the range 1..6
//For repeated uses, both can be bound together:
auto dice = std::bind ( distribution, generator );
// calling dice() will generate number in the range 1..6 for example int number = dice();

Just for completeness: actually you do not have to call srand() if you like that behavior, also it might be handful for debug.

Related

C++ Random number from 1 to a very large number (e.g. 25 million)

How would you make a function that generates a random number from 1 to 25 million?
I've thought about using rand() but am I right in thinking that the maximum number, RAND_MAX is = 32000 (there about)?
Is there a way around this, a way that doesn't reduce the probability of picking very low numbers and doesn't increase the probability of picking high / medium numbers?
Edit: #Jamey D 's method worked perfectly independent of Qt.
You could (should) use the new C++11 std::uniform_real_distribution
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> distribution(1, 25000000);
//generating a random integer:
double random = distribution(gen);
Have a look at ran3
http://www.codeforge.com/read/33054/ran3.cpp__html
You should be able to get what you want from it.
Ran3 is (atleast when I was still doing computational modelling) faster than rand() with a more uniform distribution, though that was several years ago. It returns a random integer value.
For example, getting the source code from the link above:
int main() {
srand(time(null));
int randomNumber = ran3(rand()) % 25000000;
int nextRandomNumber = ran3(randomNumber);
}

Dice roll - random numbers are not generating correctly C++

The code below print same random numbers all the time, I think the rand() is not working properly. Please help on this code:
#include <iostream>
int main() {
for (int i=0; i < 100; i++) {
int die1 = (rand() % 6) + 1;
std::cout << "Generated random number: " << die1 << std::endl;
}
return 0;
}
A few issues (aside from your malformed main prototype which you ought to fix).
Unless you tell it otherwise, rand() is seeded with an initial value of 1. Use srand to change that. Using the system clock time is idiomatic. Then at least your output will vary.
Taking modulus 6 will introduce statistical bias unless the generator's periodicity is a multiple of 6, which is unlikely. You will notice that effect for such a small modulus. Use a division-based approach with RAND_MAX instead: rand() / (RAND_MAX / 6 + 1) is no more of an abuse of rand() than rand() itself is an abuse of uniformity!
rand() does not have particularly good statistical properties. Consider using the Mersenne Twister generator that's now part of the C++ standard library. For a casino-quality generator, you'd probably have to resort to using external hardware.
Whatever you adopt, you can always run a chi square test for uniformity against your sample, too see if it has adequate statistical properties.
There is a 16% probability that you will get the same number twice in a row. rand() always return the same sequence for the same seed. What you are seeing is not necessarily incorrect. If you remove the %, what responses do you see? Are you seeing the same numbers?
Try calling srand((unsigned) time(&t)) before your while loop and see the results. They should be different from one execution run to the next.

Random() efficiency in C++

I am writing function where I need to find the random number between 1 - 10. One of the easiest way is to use random() libc call. I am going to use this function a lot. But I don't know how efficient it will be. If any one has idea about efficiency of random() that will be a help ?
Also I notice that random() give the same pattern in 2 runs.
int main()
{
for(int i=0;i<10;i++)
{
cout << random() % 10 << endl;
}
}
Output 1st time :- 3 6 7 5 3 5 6 2 9 1
Second time also I got same output.
Then how come it's random ?
Others have explained why it's the same sequence every time, but this is how you generate a random number with C++:
#include <random>
int main() {
std::random_device rd{}; //(hopefully) truly random device
std::mt19937 engine{rd()}; //seed a pseudo rng with random_device
std::uniform_int_distribution<int> d(1,10); //1 to 10, inclusive
int RandNum = d(engine); //generate
return 0;
}
http://en.cppreference.com/w/cpp/numeric/random
The actual execution time depends on your platform of course, but it is pretty much straight forward, couple multiplication and divisions or shifts:
What common algorithms are used for C's rand()?
I don't think you should be worried. If you need a lot of random numbers, then another random source probably would be a better choice for you.
If you are looking for tweaks, how about splitting the result from rand() into individual digits to get several results per call.
This way is very simple and effective, you only need to set the seed:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(){
srand(time(NULL));
for(int i=0;i<10;i++)
cout << rand() % 10 << endl;
}
To fix the problem of getting same pattern in 2 runs just add the function randomize()

rand() gives still the same value

I noticed that while practicing by doing a simple console-based quiz app. When I'm using rand() it gives me the same value several times in a row. The smaller number range, the bigger the problem is.
For example
for (i=0; i<10; i++) {
x = rand() % 20 + 1;
cout << x << ", ";
}
Will give me 1, 1, 1, 2, 1, 1, 1, 1, 14, - there are definetely too much ones, right? I usually got from none to 4 odd numbers (rest is just the same, it can also be 11, 11, 11, 4, 11 ...)
Am I doing something wrong? Or rand() is not so random that I thought it is?
(Or is it just some habit from C#/Java that I'm not aware of? It happens a lot to me, too...)
If I run that code a couple of times, I get different output. Sure, not as varied as I'd like, but seemingly not deterministic (although of course it is, since rand() only gives pseudo-random numbers...).
However, the way you treat your numbers isn't going to give you a uniform distribution over [1,20], which I guess is what you expect. To achieve that is rather more complicated, but in no way impossible. For an example, take a look at the documentation for <random> at cplusplus.com - at the bottom there's a showcase program that generates a uniform distribution over [0,1). To get that to [1,20), you simply change the input parameters to the generator - it can give you a uniform distribution over any range you like.
I did a quick test, and called rand() one million times. As you can see in the output below, even at very large sample sizes, there are some nonuniformities in the distribution. As the number of samples goes to infinity, the line will (probably) flatten out, using something like rand() % 20 + 1 gives you a distribution that takes very long time to do so. If you take something else (like the example above) your chances are better at achieving a uniform distribution even for quite small sample sizes.
Edit:
I see several others posting about using srand() to seed the random number generator before using it. This is good advice, but it won't solve your problem in this case. I repeat: seeding is not the problem in this case.
Seeds are mainly used to control the reproducibility of the output of your program. If you seed your random number with a constant value (e.g. 0), the program will give the same output every time, which is useful for testing that everything works the way it should. By seeding with something non-constant (the current time is a popular choice) you ensure that the results vary between different runs of the program.
Not calling srand() at all is the same as calling srand(1), by the C++ standard. Thus, you'll get the same results every time you run the program, but you'll have a perfectly valid series of pseudo-random numbers within each run.
Sounds like you're hitting modulo bias.
Scaling your random numbers to a range by using % is not a good idea. It's just about passable if your reducing it to a range that is a power of 2, but still pretty poor. It is primarily influenced by the smaller bits which are frequently less random with many algorithms (and rand() in particular), and it contracts to the smaller range in a non-uniform fashion because the range your reducing to will not equally divide the range of your random number generator. To reduce the range you should be using a division and loop, like so:
// generate a number from 0 to range-1
int divisor = MAX_RAND/(range+1);
int result;
do
{
result = rand()/divisor;
} while (result >= range);
This is not as inefficient as it looks because the loop is nearly always passed through only once. Also if you're ever going to use your generator for numbers that approach MAX_RAND you'll need a more complex equation for divisor which I can't remember off-hand.
Also, rand() is a very poor random number generator, consider using something like a Mersenne Twister if you care about the quality of your results.
You need to call srand() first and give it the time for parameter for better pseudorandom values.
Example:
#include <iostream>
#include <string>
#include <vector>
#include "stdlib.h"
#include "time.h"
using namespace std;
int main()
{
srand(time(0));
int x,i;
for (i=0; i<10; i++) {
x = rand() % 20 + 1;
cout << x << ", ";
}
system("pause");
return 0;
}
If you don't want any of the generated numbers to repeat and memory isn't a concern you can use a vector of ints, shuffle it randomly and then get the values of the first N ints.
Example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
//Get 5 random numbers between 1 and 20
vector<int> v;
for(int i=1; i<=20; i++)
v.push_back(i);
random_shuffle(v.begin(),v.end());
for(int i=0; i<5; i++)
cout << v[i] << endl;
system("pause");
return 0;
}
The likely problems are that you are using the same "random" numbers each time and that any int mod 1 is zero. In other words (myInt % 1 == 0) is always true. Instead of %1, use % theBiggestNumberDesired.
Also, seed your random numbers with srand. Use a constant seed to verify that you are getting good results. Then change the seed to make sure you are still getting good results. Then use a more random seed like the clock to teat further. Release with the random seed.

How do I generate totally a random number at a time?

I want to create 3 random number at a time (simultaneously). However, they returned me the same numbers at a time even though they are actually random. Example:
------------------------
Variable: A B C
------------------------
Time 1 : 5 5 5
Time 2 : 3 3 3
Time 3 : 9 9 9
------------------------
They suppose to be different numbers at all. From the observation, I can see that my code can only pick a random number at a time (interval 1 second). Here is my generator code that I'm using:
unsigned int CMain::GenerateRandom(int min, int max)
{
srand((unsigned)time(0));
unsigned int random_integer;
int lowest = min, highest = max;
int range = (highest - lowest) + 1;
random_integer = lowest + int(range * rand() / (RAND_MAX + 1.0));
return random_integer;
}
How could I generate a totally random numbers at a time? Please help.
Thank you.
Your issue here is you're resetting the random seed every call using the current time which you shouldn't do.
Call srand() once before querying any random numbers - that's all and more than enough.
Right now you always reset your random seed to the exact same value (as you use current time). Random numbers in PCs aren't really random at all. The same seed will always result in the same set of random numbers generated later on. This is intentional and used in e.g. savegames for games to always have the same things happen without having to save every random number generated, etc.
Don't call srand() each time you generate a new random number. Call it once at the start of your program and then just call rand() each time you need a new random number.
FYI: Values returned from rand() are not "totally random". They are pseudo-random numbers generated by an algorithm. (This is not related to your question though.)
The problem is that you are calling srand() for every iteration. Srand() is setting a seed based on the current timestamp. Therefore you only need to call srand() once, and just call rand() to generate a new pseudo-random number. I say pseudo-random because computers cannot generate truly random numbers.
Sample code:
#include <iostream>
#include <cstdlib>
int main()
{
int i, r;
srand(time(0));
for(i = 0; r <= 20000; i++)
r = rand();
return 0;
}
time(0) changes slowly. If you query GenerateRandom quickly you can get the same number multiple times.
But in general, that isn't a right way to generate random numbers. You want to seed the random number generator only once, before any other function uses it. Treat rand as a global singleton object. If any of your functions modifies its seed by calling srand, then the change will affect all other calls to rand.