Do not use rand()
!
If you are looking for precision in the randomness distributions, leave rand()
. Using rand()
is not only inappropriate because it is a C language utility (being your question about C ++) but it is also because the use you are giving is distorting the distribution.
Distribution of rand()
.
The rand()
function returns an integer, pseudorandom number between 0
and RAND_MAX
(both included). The distribution of the resulting values to call rand()
is uniform , that is: all the numbers between 0
and RAND_MAX
have the same probability of being obtained.
Break the distribution of rand()
.
Assuming that the interval of rand()
is [0, 32767], if the result you operate it with modulus ( %
) on a number that is not divisor of the maximum value of the interval (in your case 100
) you will be falsifying the distribution: since the remainder of dividing 32767 by 100 is 67, the numbers from 0 to 67 are more likely to appear than numbers 68 to 99.
What should you do?
As I said, you should stop using rand()
, which besides being not a C ++ utility, you were using it badly! The appropriate way to approach your problem is to use <random>
the library of pseudo-random C ++ numbers that allows you to choose the probability distribution (uniform, Bernoulli, Poisson, normal, discrete, constant, linear ...) , the underlying type of the generated value and even the algorithm to be used (minstd, mt19937, ranlux, knuth ...).
In your case, since your probabilities are divided in two:
Did I get a ball? will be fulfilled 1 in 20 times (5%).
If I have taken a ball, what color is it? (15% gold, 15% red, 30% blue and 40% green).
For the first probability, you could use a Bernoulli distribution , which allows you to set the probability of an event (take out ball) happen:
std::random_device device;
std::mt19937 generador(device());
std::bernoulli_distribution distribucion(0.05);
if (distribucion(generador));
{
// Entramos en este if un 5% de las veces.
}
For the second probability, you could use a discrete distribution , which allows you to distribute the weight of each probability (the probability of appearance of each ball):
std::random_device device;
std::mt19937 generador(device());
std::discrete_distribution<> distribucion({15, 15, 30, 40});
switch(distribucion(generador))
{
case 0: std::cout << "Pelota dorada\n"; break;
case 1: std::cout << "Pelota roja\n"; break;
case 2: std::cout << "Pelota azul\n"; break;
case 3: std::cout << "Pelota verde\n"; break;
}
You can see an example of this working in Wandbox 三 へ (へ ਊ) へ ハ ッ ハ ッ .