How to program a dice? from 1-6 only!

How to program a dice? from 1-6 only!
You can mimic a dice roll by generating a random number between 1 and 6. This is done by calling the function "rand()".

int roll = dice%6+1;

To generate new randoms on each run, you need to seed it first, by using srand(someNumberYouCanChoose).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <time.h>

int main() {

	srand(time(NULL));
	int i = 0;
	for (i = 0; i < 100; i++) {
		int dice = (rand() % 6) + 1;
		printf("%d\n",dice);
	}

        return 0;
}
Last edited on
> (rand() % 6) + 1;

Better would be to take all the bits of the pseudo random number into account:
int( std::rand() / ( ( double(RAND_MAX) + 1 ) / 6 ) ) ;

Or with C++11:
1
2
3
4
5
6
7
8
9
10
11
12
#include <random> // C++11
#include <ctime>
#include <iostream>

int main()
{
    static std::mt19937 engine( std::time(nullptr) ) ;
    static std::uniform_int_distribution<> distribution( 1, 6 ) ;
    auto die = [&] () { return distribution(engine) ; } ;

    for( int i=0 ; i<10 ; ++i ) std::cout << die() << '\n' ;
}



Last edited on
@JLBorges: Would it be possible to explain the difference in what you do versus the "easy" way?
> Would it be possible to explain the difference

std::rand() returns a pseudo-random number in the interval [ 1, RAND_MAX ]. Let us say, we need a number in the interval [ 0, N ] for some N. To make this easier for me to explain, let us say N == 15.

rand() % 16 picks up the least significant four bits in the integer and completely ignores the high order bits. Even though the sequence of integers generated may be statistically random, the sequence of the least significant four bits may not be all that random.

( N / ( double( RAND_MAX +1 ) ) * 16 would take all the bits into account, and shield us against poor dimensional distribution of the bits in the generated sequence.


On second thoughts, or did you want an explanation of the code using C++11 <random> ?
Last edited on
this would be a simple die class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class die
{
      public:
      int number;
      die()
      {
           srand(time(NULL)+rand());
           number=rand()%6+1;
           }
      void roll()
      {
           srand(time(NULL)+rand());
           number=rand()%6+1;
           }
      };
@JLBorges: Just the meaning was enough, thanks!
I'm not sure I see the problem though. If the full 32/64bits are worthy of the name "random", then any subset of the bits should be too. If we generate a (unform) random number between [0,1000[, the odds of the last digit being 1 are equal to the odds of the last digit being 6 (or any other digit, obviously). This should be the same for any number/representation [provided the original number is sufficiently large compared to the 'cutoff point'/range].
> If the full 32/64bits are worthy of the name "random", then any subset of the bits should be too.

With that definition, the sequence of numbers generated by the most implementations of the C library rand() - std::rand() in C++ - is not worthy of the name "random". The only state maintained by the random number generator is a single integral value and because of that the implementations use a Linear Congruential Generator.

The most efficient LCGs have an m equal to a power of 2, most often m = 232 or m = 264, because this allows the modulus operation to be computed by merely truncating all but the rightmost 32 or 64 bits. - wiki
http://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use

Further down in the same wiki article, we have:
A further problem of LCGs is that the lower-order bits of the generated sequence have a far shorter period than the sequence as a whole if m is set to a power of 2
...

The low-order bits of LCGs when m is a power of 2 should never be relied on for any degree of randomness whatsoever.
...


Almost all implementations of std::rand() use a modulus which is a power of two - typically 232 as can be seen from the table. (The Microsoft implementation doesn't give one a chance to use the lower order bits - it discards them entirely before returning a value to the user. This takes care of the poor randomness of low order bits, at the cost of drastically reducing RAND_MAX).


A better pseudo random number generator like std::mt19937 would be a lot closer to your expectations.
Makes sense. Thanks for the explanation!
Topic archived. No new replies allowed.