Simulating many dice rolls

Started by
20 comments, last by Sneftel 13 years, 5 months ago
Quote:Original post by Penance
Quote:Original post by Sneftel
Waitasec.
Quote:Original post by Penance
Say I want to simulate 2d6. That means there are 6^2 = 36 possibilities that map to 11 buckets (2-12). I'd love to be able to call rand() once and get 0-35 as a result, and then map that back to the 2-12 range while preserving the proper probability distribution.
You'd love to use a map to do addition for you?


Not sure what you mean. =(

output = input%6 + input/6 + 2 . It's just addition.
Advertisement
Quote:Original post by alvaro
A very low-tech solution that saves you lots of calls to rand() is to extract more than one die roll from each call to rand().

*** Source Snippet Removed ***


Hmm interesting, thanks!
Quote:Original post by Sneftel
Quote:Original post by Penance
Quote:Original post by Sneftel
Waitasec.
Quote:Original post by Penance
Say I want to simulate 2d6. That means there are 6^2 = 36 possibilities that map to 11 buckets (2-12). I'd love to be able to call rand() once and get 0-35 as a result, and then map that back to the 2-12 range while preserving the proper probability distribution.
You'd love to use a map to do addition for you?


Not sure what you mean. =(

output = input%6 + input/6 + 2 . It's just addition.


I don't think that works though...

16%6 + 16/6 + 2 = 8, not 7
Quote:Original post by Penance
16%6 + 16/6 + 2 = 8, not 7
What's your point? Iterate through the inputs 0-35, and you will get the correct number of 2s output, the correct number of 3s ouptut, and so on up to the correct number of 12s output.
Also, if you are rolling 20D6, is it that important that you get the exact distribution? You start running pretty quickly into the law of large numbers, which tells you that a normal distribution is a very good approximation to your roll. Then just use an algorithm that samples a normal distribution.

In the case of rolling 20D6, you can use N(70,7.63762615825973334425) as a very good approximation. Then round the result, or something (I am not sure what these numbers are being used for).

If you do want an exact distribution, Sneftel's algorithm can be generalized to higher numbers.
#include <cmath>#include <iostream>#include <map>int dice_roll(int number_of_dice, int number_of_sides, int seed) {  int accumulator = 0;  for (int i = 0; i < number_of_dice; i++) {    accumulator += (seed % number_of_sides);    seed /= number_of_sides;  }  return accumulator + number_of_dice;}int main(int, char **) {  std::map<int, int> results;  for (int i = 0; i < 6*6*6*6; i++) {    ++(results[dice_roll(4, 6, i)]);  }  for (std::map<int, int>::iterator itr = results.begin(); itr != results.end(); ++itr) {    std::cout << itr->first << " - " << itr->second << std::endl;  }  return 0;}

Of course, this then becomes dependent of the quality of the underlying random number generator you're using. Using something like a linear congruential generator will probably skew your numbers for large numbers of dice.
Quote:Original post by Sneftel
Quote:Original post by Penance
16%6 + 16/6 + 2 = 8, not 7
What's your point? Iterate through the inputs 0-35, and you will get the correct number of 2s output, the correct number of 3s ouptut, and so on up to the correct number of 12s output.


I appreciate your response, but I think you're overestimating my ability to understand what's going on. ;)

Can you explain what your solution is actually doing and why it produces the correct distribution?

If I generalized this, it would be input%d + input/d + n for n d-sided dice with input [0, d^n - 1] right?
Quote:Original post by Penance
If I generalized this, it would be input%d + input/d + n for n d-sided dice with input [0, d^n - 1] right?

No, see the code sample directly above your post.
Quote:Original post by alvaro
Also, if you are rolling 20D6, is it that important that you get the exact distribution? You start running pretty quickly into the law of large numbers, which tells you that a normal distribution is a very good approximation to your roll. Then just use an algorithm that samples a normal distribution.

In the case of rolling 20D6, you can use N(70,7.63762615825973334425) as a very good approximation. Then round the result, or something (I am not sure what these numbers are being used for).


I suppose it doesn't need to be a perfect distribution, just a fair one.

Basically, each player will get to roll a certain kind of dice for every X points they have in a skill, then those scores get compared and a modifier is computed.

So, maybe for every 8 defense you get to roll 1d4, and for every point difference between the players' scores you get a certain % damage reduction.
Quote:Original post by no such user
Quote:Original post by Penance
If I generalized this, it would be input%d + input/d + n for n d-sided dice with input [0, d^n - 1] right?

No, see the code sample directly above your post.


Thanks =)

This topic is closed to new replies.

Advertisement