Rice Rolling with Probability

Hello guys!
I have a question. I'm able to produce correct sums and count those sums in an array but I can't implement the probability into my program. I understand the probability of rolling two dice but I can't figure out how to put it into my program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
using namespace std;



int main(int argc, int **argv) {
	int nrOfRolls;
	int die1;
	int die2;
	int sumDice;
	int store[14];
	int k = 0;
	int userExit = 1;


	while (userExit == 1) {
		srand(time(0));
		cout << "Please enter number of rolls: ";
		cin >> nrOfRolls;

		for (; k < 14; k++)
			store[k] = 0;


		for (k = 0; k < nrOfRolls; k++) {
			die1 = rand() % 6 + 1;
			die2 = rand() % 6 + 1;
			sumDice = die1 + die2;
			store[sumDice]++;
			//CODE BELOW IS TO COUNT THE SUM OF DICE
			//cout << "Sum of Dice: " << sumDice << "\n";		
		}


		cout << setw(11) << "Sum" << setw(15) << "#Rolled" << setw(20) << "Odds" << setw(25) << "%Error" << endl;


		for (k = 2; k <= 12; k++) {
			cout << setw(10) << k << ":" << setw(10) << store[k] << endl;
		}

		cout << "Try again? (1 = Yes, 0 = Exit)" << endl;
		cin >> userExit;
	}

	cout << "Thank you! Now exiting..." << endl;

	system("PAUSE");
	return 0;

}


And, for example, the change of rolling a 2 is a 1/36 chance. I just can't figure out the odds.

Can I have some help?
I'm not exactly sure what you mean when you differentiate "chance" from "odds"; they are equivalent terms in my mind.

For a sample size as small as 2 dice rolls, you can pretty much brute-force the probability calculations.

Sample space:

(1,1)	(1,2)	(1,3)	(1,4)	(1,5)	(1,6)
(2,1)	(2,2)	(2,3)	(2,4)	(2,5)	(2,6)
(3,1)	(3,2)	(3,3)	(3,4)	(3,5)	(3,6)
(4,1)	(4,2)	(4,3)	(4,4)	(4,5)	(4,6)
(5,1)	(5,2)	(5,3)	(5,4)	(5,5)	(5,6)
(6,1)	(6,2)	(6,3)	(6,4)	(6,5)	(6,6)


Sum of each outcome:

(2)	(3)	(4)	(5)	(6)	(7)
(3)	(4)	(5)	(6)	(7)	(8)
(4)	(5)	(6)	(7)	(8)	(9)
(5)	(6)	(7)	(8)	(9)	(10)
(6)	(7)	(8)	(9)	(10)	(11)
(7)	(8)	(9)	(10)	(11)	(12)


Each individual outcome has a 1/36 chance, but clearly 3+4 is the same as 4+3, so you can combine those.

Histogram:


                *
             *  *  *
          *  *  *  *  *
       *  *  *  *  *  *  *
    *  *  *  *  *  *  *  *  * 
 *  *  *  *  *  *  *  *  *  *  *
 2  3  4  5  6  7  8  9 10 11 12

(anything else is a 0% chance)

From the histogram, you can see there are 2 ways to roll a 3, so there's a 2*(1/36) chance of rolling a 3, or a 1/18 chance. There are 6 ways to roll a 7, so that's a 1/6 chance.

One way to code this triangle would be something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Example program
#include <iostream>
#include <string>

double die_sum_chance(int sum)
{
    if (sum < 2 || sum > 12)
        return 0;
    if (sum <= 7)
        return static_cast<double>(sum - 1)  / 36;
    else
        return static_cast<double>(12 - (sum - 1)) / 36;
}

int main()
{
    for (int i = 0; i <= 14; i++)
    {
        std::cout << "Roll a " << i << ": " <<  36 * die_sum_chance(i) << "/" << 36 << " chance" << std::endl;
    }
}


When you add two uniform distributions together, you get a triangle distribution. (If you know anything about convolution, that's equivalent to convolving the two square pulses together... but that's a different topic.)
That helped out a ton, thanks! Using that new function now gives me the odds while doing correct calculations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

2/8/18
CIT 245
Rolling Dice with ODDS
LAST EDIT:
2/8/18 FIXED BUG WTH ARRAY NOT RESETTING ITS VALUE
2/9/18 INTRODUCED THE FUNCTION die_sum_chance TO CALCULATE THE ODDS AND %ERROR
*/

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
using namespace std;

double die_sum_chance(int sum)
{
	if (sum < 2 || sum > 12)
		return 0;
	if (sum <= 7)
		return double(sum - 1) / 36;
	else
		return double(12 - (sum - 1)) / 36;
}


int main(int argc, int **argv) {
	int nrOfRolls;
	int die1;
	int die2;
	int sumDice;
	int store[14];
	int k = 0;
	int userExit = 1;
	double odds;


	while (userExit == 1) {
		srand(time(0));
		cout << "Please enter number of rolls: ";
		cin >> nrOfRolls;

		for (k=0 ; k < 14; k++)
			store[k] = 0;


		for (k = 0; k < nrOfRolls; k++) {
			die1 = rand() % 6 + 1;
			die2 = rand() % 6 + 1;
			sumDice = die1 + die2;
			store[sumDice]++;
			//CODE BELOW IS TO COUNT THE SUM OF DICE. ENABLE FOR DEBUGGING
			//cout << "Sum of Dice: " << sumDice << "\n";		
		}


		cout << setw(11) << "Sum" << setw(15) << "#Rolled" << setw(20) << "Odds" << setw(25) << "%Error" << endl;


		for (k = 2; k <= 12; k++) {
			odds = die_sum_chance(k)* nrOfRolls;
			cout << setw(10) << k << ":" << setw(10) << store[k] << setw(23) << odds << setw(27) << (abs(store[k] - odds) / odds) * 100 << "%" << endl;
		}

		cout << "Try again? (1 = Yes, 0 = Exit)" << endl;
		cin >> userExit;
	}

	cout << "Thank you! Now exiting..." << endl;

	system("PAUSE");
	return 0;

}


Do you think there should be a change in the code for efficiency?
only if it is taking too long to run. ?

store could be unsigned if you want to run big tests.

die1, die2, and sumdie can all be eliminated.
store[rand()%6+rand%6+2]++;

store can be initialized
int store[14] = {0}; //this only works with zero, though.

with these changes, I predict that if you tried to do 10^100000000 rolls it would run approximately 1/100000000000th of a second faster.

the only thing taking any real time in your program are the print statements which are inherently slow and there isn't anything you can do about that.

the c++ headers are <ctime> and <cstdlib>. Use those, or one day it will bite you.
Last edited on
Topic archived. No new replies allowed.