1

Based off of some articles I read, I created a dice roll function as thus:

#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;

short roll_dice(short number_of_dice, short die_strength) {
    short all_rolls_sum = 0;
    short individual_roll = 0;  
    for (short i = number_of_dice; i > 0; i--) {
        srand(time(NULL));
        individual_roll = (rand() % die_strength) +1;
        all_rolls_sum += individual_roll;
    }
    return all_rolls_sum;
}

The program I used to run this function is:

int main() {
    cout << roll_dice(1, 6);
    return 0;
}

This is meant to simulate a 1d6 die roll. The results were what I expected (i.e. 2, 4, 3, 5, 6, 4, 4, 1) returning both odd numbers and even numbers. However, the problem is that, when I input 2 for the first parameter, I am only getting even numbers returned (i.e. 2, 2, 6, 8, 6, 4, 4, 8). It turns out that any time I input an odd number for the first parameter (number_of_dice), I get both even and odd numbers returned. If I input an even number for the number_of_dice, I get only even.

I am still relatively new to C++/programming but is this an issue with the modulo being used in the (rand() % die_strength) +1 portion of my code?

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • 5
    Why does your code call `srand` more than once? – Eljay Jan 02 '20 at 18:25
  • @Dortimer What "decimal"? – Acorn Jan 02 '20 at 18:28
  • @Eljay It's only used once, and rand() is only used once as well. – the-wastelander Jan 02 '20 at 18:29
  • 4
    The `time` function usually have a resolution of one seconds only, which means if you call `time(NULL)` multiple times in the same second you will get the same value returned. Now if you use this as a seed for `srand` in a tight loop that will iterate multiple times within a second then you will reset the seed, causing `rand` to return the same value over and over again. C++ have some very nice facilities for [pseudo-random number generation](https://en.cppreference.com/w/cpp/numeric/random) beyond `srand` and `rand`, I suggest you use them instead. – Some programmer dude Jan 02 '20 at 18:32
  • @Someprogrammerdude I will definitely check those other random/pseudo-random resources out. Thank you for the explanation. – the-wastelander Jan 02 '20 at 18:40

2 Answers2

3

As @Eljay points out, you are calling srand() once per roll.

Since time(NULL) has a resolution of 1 second, and most likely the function is running within the same second, you are getting the same output, which means individual_roll ends up being the same number.

Therefore you end up with the relation:

all_rolls_sum = number_of_dice * individual_roll

If number_of_dice is 2, then your numbers are all even.

Acorn
  • 24,970
  • 5
  • 40
  • 69
1

You are setting your seed to the same value in every roll so your roll should be the same most of the times.

Try to only set the seed once before starting the rolls.

The following gives you 100 rolls

#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;

short roll_dice(short number_of_dice, short die_strength) {
    short all_rolls_sum = 0;
    short individual_roll = 0;  
    for (short i = number_of_dice; i > 0; i--) {
        individual_roll = (rand() % die_strength) +1;
        all_rolls_sum += individual_roll;
    }
    return all_rolls_sum;
}

int main() {
    srand(time(NULL));
    for (int i = 0; i < 100; i++) {
        cout << roll_dice(1, 6);
    }
    return 0;
}