In this experiment, I roll two dice. The probability distribution for the sum of two dice is as follows:

0: 0.000000
1: 0.000000
2: 0.027778
3: 0.055556
4: 0.083333
5: 0.111111
6: 0.138889
7: 0.166667
8: 0.138889
9: 0.111111
10: 0.083333
11: 0.055556
12: 0.027778


This is how to calculate the above distribution:

for (int i = 1; i <= NUM_SIDES; ++i)
for (int j = 1; j <= NUM_SIDES; ++j)
dist[i + j] += 1.0;

for (int k = 2; k <= 2 * NUM_SIDES; ++k)
dist[k] /= 36.0;

where NUM_SIDES is 6 for a six-sided dice.

It's also possible to obtain the distribution empirically by running a certain number of experiments (in this case rolling two dice) up to the point when we are satisfied with the precision of results. For example, the following list shows the numbers of experiments (in eight separate runs of the program) that match the probability distribution to three decimal places:

• 191,788
• 1,796,504
• 1,850,779
• 442,138
• 1,176,835
• 450,513
• 3,875,791
• 4,339,549

Below, there are two examples of distributions obtained empirically:

0: 0.000000
1: 0.000000
2: 0.027938
3: 0.055320
4: 0.083072
5: 0.111009
6: 0.138231
7: 0.166997
8: 0.138997
9: 0.111971
10: 0.083579
11: 0.055329
12: 0.027595

0: 0.000000
1: 0.000000
2: 0.027873
3: 0.055724
4: 0.083431
5: 0.111157
6: 0.138746
7: 0.166282
8: 0.138999
9: 0.111383
10: 0.083352
11: 0.055454
12: 0.027606


This is the program I used to obtain the above results:

using System;
using System.Collections.Generic;

namespace ConsoleTest
{
class Program
{
const int NUM_SIDES = 6;

static double[] dist = new double[2 * NUM_SIDES + 1];

// The frequencies of occurrence of values between 2 and 12 (the sum of two random integers between 1 and 6).
static int[] freq = new int[2 * NUM_SIDES + 1];

// The probability distribution of the occurrence of values between 2 and 12.
static double[] prob = new double[2 * NUM_SIDES + 1];

static void Main(string[] args)
{
// Calculate the distribution for the sum of two dice.
CalculateDistribution();

Random rnd = new Random();

// Run experiments N times until empirical results match the exact results to
// three decimal places.
int N = 1;
bool match = false;
while (!match)
{
// Obtain the sum of two random integers each between 1 and 6 i.e. an integer value between 2 and 12.
int num = rnd.Next(1, 7) + rnd.Next(1, 7);

// Register the frequency of occurrence of the integer value between 2 and 12.
freq[num] += 1;

// Compute probability of the occurrence of the value between 2 and 12.
prob[num] = (double)freq[num] / (double)N;

// Check if the empirical results match the exact values to three decimal places.
match = true;
for (int i = 2; i < dist.Length; ++i) // we can start from index=2 because probability of 0 and 1 is always 0.0
{
if ((int)(dist[i] * 1000) != (int)(prob[i] * 1000))
{
match = false;
break;
}
}

++N;
}

Console.WriteLine("The number of experiments performed: {0:N0}\n", N - 1);

// Show the distributions.
Console.WriteLine("Exact values:");
for (int i = 0; i < dist.Length; ++i)
Console.WriteLine("{0}: {1:F6}", i, dist[i]);

Console.WriteLine();

Console.WriteLine("Epirical results values:");
for (int i = 0; i < prob.Length; ++i)
Console.WriteLine("{0}: {1:F6}", i, prob[i]);
}

static void CalculateDistribution()
{
for (int i = 1; i <= NUM_SIDES; ++i)
for (int j = 1; j <= NUM_SIDES; ++j)
dist[i + j] += 1.0;

for (int k = 2; k <= 2 * NUM_SIDES; ++k)
dist[k] /= 36.0;
}
}
}


You can download the source code from here.