Navigate / search

Dice Game Simulation

The other day I played a dice game with the in-laws. Here’s the basics:
You start with five dice. Give a roll and see what you have. If you have any 5’s or 2’s you take out the dice that have the 5’s or 2’s and roll again (you get a zero for that round). If you roll and do not have any 5’s or 2’s, you add up all the dice and roll again. Your points accumulate through the rounds until you have no dice left.

So here is an example:
: You roll a 5, 4, 3, 2, and a 4
Since you rolled a 5 and a 2, you take those two dice out and roll again (still with zero points)
: You roll a 2, 1, and a 1
Since you rolled a 2, you take that die out and roll again (still with zero points)
: You roll a 3 and 4
No 5’s or 2’s, so you add up the dice and that is the start to your running total: 7
: You roll a 4 and 4
No 5’s or 2’s, so you add up the dice and add to your running total: 7 + 8 = 15
: You roll a 2 and 2
Bummer, all your dice were 5’s or 2’s, so you are out of dice with a final score of 15

Pretty simple, right? I quickly realized that there was no actual thought process to the game it was really just the luck of the dice that gave you a score. So naturally I wanted to write a simulation to see what a normal score looks like on a large scale.

I put together a little bit of code and came up with the following results:

Rolls Distribution for 10000 games
Rolls: ##Graph## Percent% (Count)
01: # 0.37% (37)
02: ##### 4.53% (453)
03: ############ 11.61% (1161)
04: ################# 16.83% (1683)
05: ################ 15.73% (1573)
06: ############### 14.11% (1411)
07: ############ 11.3% (1130)
08: ######## 7.78% (778)
09: ###### 5.53% (553)
10: #### 3.89% (389)
11: ### 2.73% (273)
12: ## 1.64% (164)
13: ## 1.31% (131)
14: # 0.74% (74)
15: # 0.77% (77)
16: # 0.41% (41)
17: # 0.26% (26)
18: # 0.16% (16)
19: # 0.08% (8)
20: # 0.08% (8)
21: # 0.03% (3)
22: # 0.04% (4)
23: # 0.03% (3)
24: # 0.01% (1)
25: # 0.02% (2)
27: # 0.01% (1)

Score Distribution for 10000 games
Score: ##Graph## Percent% (Count)
000: ##################### 20.54% (2054)
001: ## 2% (200)
002: # 0.66% (66)
003: ### 2.56% (256)
004: #### 3.85% (385)
005: ## 1.91% (191)
006: #### 3.45% (345)
007: #### 3.27% (327)
008: ### 2.13% (213)
009: ### 2.31% (231)
010: #### 3.35% (335)
011: ### 2.29% (229)
012: ### 2.76% (276)
013: ### 2.44% (244)
014: ### 2.54% (254)
015: ### 2.16% (216)
016: ### 2.12% (212)
017: ### 2.42% (242)
018: ## 1.88% (188)
019: ### 2.04% (204)
020: ### 2.06% (206)
021: ## 1.81% (181)
022: ## 1.92% (192)
023: ## 1.73% (173)
024: ## 1.61% (161)
025: ## 1.44% (144)
026: ## 1.33% (133)
027: ## 1.25% (125)
028: ## 1.27% (127)
029: ## 1.25% (125)
030: ## 1.03% (103)
031: ## 1.09% (109)
032: # 0.95% (95)
033: # 0.77% (77)
034: # 0.96% (96)
035: # 0.74% (74)
036: # 0.82% (82)
037: # 0.76% (76)
038: # 0.63% (63)
039: # 0.53% (53)
040: # 0.7% (70)
041: # 0.7% (70)
042: # 0.66% (66)
043: # 0.55% (55)
044: # 0.49% (49)
045: # 0.52% (52)
046: # 0.43% (43)
047: # 0.42% (42)
048: # 0.4% (40)
049: # 0.28% (28)
050: # 0.32% (32)
051: # 0.33% (33)
052: # 0.18% (18)
053: # 0.18% (18)
054: # 0.17% (17)
055: # 0.29% (29)
056: # 0.2% (20)
057: # 0.18% (18)
058: # 0.18% (18)
059: # 0.12% (12)
060: # 0.17% (17)
061: # 0.11% (11)
062: # 0.1% (10)
063: # 0.16% (16)
064: # 0.14% (14)
065: # 0.1% (10)
066: # 0.08% (8)
067: # 0.08% (8)
068: # 0.1% (10)
069: # 0.07% (7)
070: # 0.05% (5)
071: # 0.07% (7)
072: # 0.07% (7)
073: # 0.07% (7)
074: # 0.05% (5)
075: # 0.07% (7)
076: # 0.05% (5)
077: # 0.05% (5)
078: # 0.01% (1)
079: # 0.04% (4)
080: # 0.04% (4)
081: # 0.05% (5)
082: # 0.02% (2)
083: # 0.05% (5)
084: # 0.02% (2)
085: # 0.05% (5)
087: # 0.02% (2)
088: # 0.03% (3)
090: # 0.01% (1)
091: # 0.01% (1)
092: # 0.02% (2)
094: # 0.01% (1)
095: # 0.02% (2)
096: # 0.01% (1)
098: # 0.01% (1)
099: # 0.01% (1)
100: # 0.02% (2)
107: # 0.02% (2)
116: # 0.01% (1)

Average rolls: 6
Average score: 16

So apparently the average score is 16 and the average number of rolls is 6. The average score was lower than I expected and the average number of rolls was higher than expected. But hey, I’d love to get a round that scores 116, that’d be pretty awesome.

Anyway, I’ll paste the code below. The program takes one parameter, an integer of the number of games you want to simulate. It also prints out the results of each game as such:

Game 1
2, 6, 6, 5, 2
2, 5
game total: 0

Game 2
3, 6, 4, 1, 2
4, 1, 4, 1
6, 4, 4, 2
4, 1, 2
5, 5
game total: 10

(…)

Game 9999
6, 6, 3, 1, 1
4, 4, 4, 1, 1
6, 5, 3, 6, 2
6, 4, 3
1, 3, 1
4, 1, 3
5, 5, 5
game total: 57

Game 10000
3, 1, 6, 4, 2
4, 4, 1, 4
1, 4, 5, 3
5, 1, 2
2
game total: 13

Pretty interesting to just look through. So here’s the code:
Tough to read without tabs, so you can alsodownload the file here

#include <iostream>
#include <cstdlib>
#include <time.h>
#include <map>

using namespace std;

int main (int argc, char * const argv[]) {
// Start with 5 dice
// Roll dice
// if any of the dice are of value 2 or 5
// remove dice that are of value 2 or 5 and roll again
// else
// add up dice and add to total score then roll again
// if there are no dice left, game over

srand(time(NULL)); // initialize random

int numberOfDice, valueOfDice[5], rollSum, totalScore, tmpNumberOfDice;
int numberOfRolls, totalGamesRolls=0, averageRolls=0;
int numberOfGames, totalGamesScores=0, averageScore=0;
bool goodRoll;
map<int, int> games;
map<int, int> numRolls;
int i,j;

numberOfGames = atoi(argv[1]);

for (j = 0 ; j < numberOfGames ; j++) {
// New game
totalScore = 0;
numberOfDice = 5;
numberOfRolls = 0;
cout << "Game " << j+1 << endl;
while (numberOfDice > 0) {
// New round
rollSum = 0;
goodRoll = true;
numberOfRolls++;
tmpNumberOfDice = numberOfDice;
for (i = 0; i < tmpNumberOfDice ; i++) {
// New roll
valueOfDice[i] = rand() % 6 + 1;
cout << valueOfDice[i];
if (i < (tmpNumberOfDice-1)) cout << ", ";
else cout << "\n";
if (valueOfDice[i] == 2 || valueOfDice[i] == 5) {
goodRoll = false;
numberOfDice--;
}
rollSum += valueOfDice[i];
}
if (goodRoll)
totalScore += rollSum;
}
cout << "game total: " << totalScore << "\n\n";
numRolls[numberOfRolls]++;
totalGamesRolls += numberOfRolls;
games[totalScore]++;
totalGamesScores += totalScore;
}

// Display rolls distribution
map<int, int>::iterator it;
float percent;

cout << "\nRolls Distribution for " << numberOfGames << " games" << endl;
cout << "Rolls: ##Graph## Percent% (Count)" << endl;
for (it = numRolls.begin() ; it != numRolls.end() ; ++it) {
percent = (float)((it->second)*100) / (float)numberOfGames;
if (it->first < 10) cout << "0";
cout << it->first << ": ";
for (i = 0 ; i < percent ; i++)
cout << "#";
cout << " " << percent << "%" << " (" << it->second << ")" << endl;
}

// Display score distribution
cout << "\nScore Distribution for " << numberOfGames << " games" << endl;
cout << "Score: ##Graph## Percent% (Count)" << endl;
for (it = games.begin() ; it != games.end() ; ++it) {
percent = (float)((it->second)*100) / (float)numberOfGames;
if (it->first < 10) cout << "0";
if (it->first < 100) cout << "0";
cout << it->first << ": ";
for (i = 0 ; i < percent ; i++)
cout << "#";
cout << " " << percent << "%" << " (" << it->second << ")" << endl;
}

averageRolls = totalGamesRolls / numberOfGames;
cout << "\nAverage rolls: " << averageRolls << endl;

averageScore = totalGamesScores / numberOfGames;
cout << "Average score: " << averageScore << endl;

return 0;
}

Leave a comment

name*

email* (not published)

website