Okay, this bugged me for several years, now. If you sucked in statistics and higher math at school, turn away, now. Too late.
Okay. Take a deep breath. Here are the rules. Take two thirty sided dice (yes, they do exist) and roll them simultaneously.
- Add the two numbers
- If both dice show <= 5 or >= 26, throw again and add the result to what you have
- If one is <= 5 and the other >= 26, throw again and subtract the result from what you have
- Repeat until either is > 5 and < 26!
If you write some code (see below), roll those dice a few million times and you count how often you receive each number as the final result, you get a curve that is pretty flat left of 1, around 45° degrees between 1 and 60 and flat above 60. The chance to roll 30.5 or better is greater than 50%, to roll better than 18 is 80% and to roll better than 0 is 97%.
Now the question: Is it possible to write a program to calculate the exact value f(x), i.e. the probability to roll a certain value?
Background: For our role playing game "Jungle of Stars" we looked for a way to keep random events in check. The rules above guarantee a much more stable outcome for something you try :)
For the geeks around, the code in Python:
import random
import sys
def OW60 ():
"""Do an open throw with a "60" sided dice"""
val = 0
sign = 1
while 1:
r1 = random.randint (1, 30)
r2 = random.randint (1, 30)
#print r1,r2
val = val + sign * (r1 + r2)
islow = 0
ishigh = 0
if r1 <= 5:
islow += 1
elif r1 >= 26:
ishigh += 1
if r2 <= 5:
islow += 1
elif r2 >= 26:
ishigh += 1
if islow == 2 or ishigh == 2:
sign = 1
elif islow == 1 and ishigh == 1:
sign = -1
else:
break
#print sign
#print val
return val
result = [0] * 2000
N = 100000
for i in range(N):
r = OW60()
x = r+1000
if x < 0:
print "Too low:",r
if i % 1000 == 0:
sys.stderr.write('%d\n' % i)
result[x] += 1
i = 0
while result[i] == 0:
i += 1
j = len(result) - 1
while result[j] == 0:
j -= 1
pSum = 0
# Lower Probability: The probability to throw this or less
# Higher Probability: The probability to throw this or higher
print "Result;Absolut Count;Probability;Lower Probability;Rel. Lower Probability;Higher Probability;Rel. Higher Probability;"
while i <= j:
pSum += result[i]
print '%d;%d;%.10f;%d;%.10f;%d;%.10f' % (i-1000, result[i], (float(result[i])/N), pSum, (float(pSum)/N), N-pSum, (float(N-pSum)/N))
i += 1