Note that there are some explanatory texts on larger screens.

plurals
  1. POCalculate exact result of complex throw of two D30
    primarykey
    data
    text
    <p>Okay, this bugged me for several years, now. If you sucked in statistics and higher math at school, turn away, <em>now</em>. Too late.</p> <p>Okay. Take a deep breath. Here are the rules. Take <em>two</em> thirty sided dice (yes, <a href="http://paizo.com/store/byCompany/k/koplow/dice/d30" rel="nofollow noreferrer">they do exist</a>) and roll them simultaneously.</p> <ul> <li>Add the two numbers</li> <li>If both dice show &lt;= 5 or >= 26, throw again and <em>add</em> the result to what you have</li> <li>If one is &lt;= 5 and the other >= 26, throw again and <em>subtract</em> the result from what you have</li> <li>Repeat until either is > 5 and &lt; 26!</li> </ul> <p>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%.</p> <p>Now the question: Is it possible to write a program to <em>calculate</em> the <em>exact</em> value f(x), i.e. the probability to roll a certain value?</p> <p>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 :)</p> <p>For the geeks around, the code in Python:</p> <pre><code>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 &lt;= 5: islow += 1 elif r1 &gt;= 26: ishigh += 1 if r2 &lt;= 5: islow += 1 elif r2 &gt;= 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 &lt; 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 &lt;= 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 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload