Test Your Dice Roller
I wanted to test the fairness of my dice library. It had been powering Dice Golem for months and I’d long before done some randomness checks, but I had no published data to prove it.
You can check out my dice
Golang package on GitHub.
Basics
Is the package’s algorithm fair at first glance? It seemed so. The rolls it made seemed high every now and again, but I wanted to dig into it.
AnyDice has been my go-to for dice probabilities for ages. I pulled the result curves for rolling 3d6:
$ cat _data/true-3d6.csv
3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
0.46,1.39,2.78,4.63,6.94,9.72,11.57,12.50,12.50,11.57,9.72,6.94,4.63,2.78,1.39,0.46
$ sed -n '2p' _data/true-3d6.csv | mkspark
▁▁▂▃▄▆▇██▇▆▄▃▂▁▁
The ideal probability curve to reach. How does my dice library stand up?
export FORMAT=json # output dice rolls as JSON
export roll="3d6"
while true; do
dice eval $roll | jq .result >> /tmp/test-$roll.txt
done
Basically, I used the package’s CLI to roll 3d6 continuously and dump every result to a text file that I could inspect later. I didn’t need to wait long:
$ wc -l /tmp/test-3d6.txt
16812 /tmp/test-3d6.txt
$ data2hist -s 16 </tmp/test-3d6.txt | mkspark
▁▁▂▃▅▆▇▇█▇▆▄▃▂▁▁
That looks promising! 16,812 results ⇒ 50,436 virtual 6-sided dice rolls. Some differences in the numbers of 7s and 10s rolled from what’s expected. The exact result percentages from the test:
$ data2hist -s 16 </tmp/test-3d6.txt | tr ' ' '\n' \
| nl -v3 | awk '{perc=100 * $2/16812; printf "%s,%.4f\n", $1, perc}' \
| transpose.py \
| sed '1s/\.0//g'
3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
0.3866,1.4394,2.8194,4.5682,7.4233,9.862,11.2063,12.2472,12.5981,11.5156,9.7609,6.882,4.5503,2.8432,1.4632,0.4342
I stuck the ideal and observed percentages together in a new CSV, so that I could build a new graph and overlay them: