Do not use rand
.
You are programming in C ++, however you follow paradigms of C and use utilities of that language; do not use rand
as it is not part of the C ++ specification and therefore may not be portable and can offer questionable results and performance. Therefore, is being studied to deprecate it .
Starting with the C ++ 11 standard, the C ++ language offers a complete library of generation of pseudorandom numbers that allows 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 ...).
You are faking distribution.
The numerical distribution of std::rand
is homogeneous between 0
and RAND_MAX
, this means that any number within that range has the same probability of being selected (1 among RAND_MAX
).
When doing module ( %
) on the result of std::rand
you break the homogeneity if the divisor is not a multiple of RAND_MAX
. Assuming a RAND_MAX
of 32767
with a module on 6
we get that the numbers from 1
to 5
have a probability of occurrence lower than the 0
(a 0.003% lower).
Proposal.
Taking into account the above, you could create a given object that includes a homogeneous distribution of values between 1 and 6:
template <int MIN, int MAX>
struct Dado
{
int lanzar()
{
/* Generamos un número pseudo-aleatorio con el algoritmo
mt19937 distribuido uniformemente entre MIN y MAX */
return distribucion(generador);
}
private:
// Tenemos control sobre el algoritmo y distribución a usar.
std::random_device device;
std::mt19937 generador{device()};
std::uniform_int_distribution<> distribucion{MIN, MAX};
};
With this Dado
object you can create a function that follows your premises:
- Launch two 6-sided dice.
- If the value is the same, throw them again.
// Alias de dado de 6 caras.
using D6 = Dado<1, 6>;
// Nuestros dados.
D6 dado1, dado2;
int tirada()
{
int tirada1, tirada2, avances{};
do
{
avances += (tirada1 = dado1.lanzar()) + (tirada2 = dado2.lanzar());
std::cout << "Primer dado: " << tirada1
<< "\nSegundo dado: " << tirada2
<< "\n\tAvances: " << avances << '\n';
} while (tirada1 == tirada2);
return avances;
}
You can see the code working in Wandbox 三 へ (へ ਊ) へ ハ ッ ハ ッ .