Two weeks ago, I found out about non-transitive dice from Hacker News. And I thought it would be a good simple project to build a 3D model for in OpenSCAD, after designing King’s Gambit, an open source 3D printable Chess set.
It was definitely a lot easier to design than the chess set, and I managed to do it in an afternoon. I probably spent more time writing up the documentation and this blog post than I did actually designing the thing.
The code repository is on github here. Feel free to fork the design and try to do other things with it, and send pull requests.
What are non-transitive dice?
Non-transitive dice are a set of dice where no one dice has a better chance of winning head-to-head with another dice in the set. They’re like the rock-paper-scissors of the dice world.
The idea for them have been around since the 1970’s: Gardner, M. “Mathematical Games: The Paradox of the Nontransitive Dice and the Elusive Principle of Indifference.” Sci. Amer. 223 , 110-114, Dec. 1970.
When you look closely at the dice, they might have more than one face with the same number of pips (the little divets), or eve no pips at all. Some might have numbers above six as well.
There are different sets of possible non-transitive dice, usually named after its inventor. The three I have implemented here are Efron, Grime, and Miwin. If you have others, feel free to fork, contribute, and send a pull request!
Efron’s dice are a set of four dice where each dice beats their predecessor by a probability of 2/3.
The dice is named and ordered by the color scheme where:
Blue > Magenta > Olive > Red > Blue
which means if you’re reading the wikipedia article, A corresponds to Blue, B to Magenta, C to Olive, and D to Red. The colors of the dice are in alphabetical order, to help you remember. This color scheme was adopted from here
Miwin’s dice are two sets of three dice each with the probability that it will have a higher number than another is 17/36; a lower number, 15/36.
Since there are only three dice, each dice will beat one and lose to the other on average.
The dice can be distinguished by color, or by the sum of their smallest two numbers. For example, the III dice in the Miwin set has faces 1 and 2 on it, which are the smallest two numbers on the dice. Add up 1 and 2, and you get 3, which is the name of that Miwin dice. Dices III, IV, and V, are in one set, and dices IX, X, and XI, are in the other.
These set of dice also has reverse non-transitivity. Normally, III beats IV. But if you remove the common faces, the dice reverses their intransitivity, meaning now IV beats III. This applies to the other two combinations of IV and V, and V and III.
Grime’s dice is a set of 5 dice, each denoted by a color, where the order of which dice beats which is ordered in two ways:
Alphabetical order of the color's name Blue > Magenta > Olive > Red > Yellow > Blue By the length of each color's name Red > Blue > Olive > Yellow > Magenta > Red
In general, the alphabetical chain is stronger than the word length chain. Overall, the average winning probability for one die is 63%
Like Miwin’s dice, Grime’s dice also has reverse non-transitivity. If you have two dice of each color, now the order for word length now flips so:
Magenta > Yellow > Olive > Blue > Red >Magenta
With two dice, the chain ordered by word-length is stronger than the alphabetical chain. The average winning probability for two dice is 59%
Grime’s dice has other fascinating properties that I suggest you look at here.
I found that I spent most of my time writing in OpenSCAD doing refactoring. I’m not sure what the problem is yet, but it’s a symptom of some underlying problem with the programming language’s interface with the user.
In addition, I also learned that you can put modules within another to help organize the code and not pollute the namespace, but there’s no way to access those modules outside of the containing module, so you can’t actually use it to namespace modules. I also leanred how to use default arguments in the module calls for friendlier programmer interface.
I also tried organizing the code so that there’s a src directory and a print directory, just like there’s a src/ and bin/ in software. However, it’s often not as simple as having a main.scad. Often times, demonstrating what it looks like assembled is different than arranging multiple pieces for printing. So I succumbed to the use of plate.scad to indicate that this is the file you should compile to STL to print. Sometimes, you have multiple plates, and you have to do all the compilation to STL by hand (unless I find a way to convert *.scad to *.stl in OpenSCAD on the command line), which makes it tedious. I think eventually, the printer driver software will allow you to arrange plates, but in the meantime, we’ll have to provide both a plate.scad and an assembly.scad.
Rounded corners are tedious to do. There are easier ways of programming rounded corners, by using the convex hull() or minkowski() methods, but both are so ridiculously slow at rendering (especially the latter), that it makes it pretty much impossible to use practically.
Well, other than that, I’m looking for other simple projects to model. Have fun with the parametric dice, and send me a pull request!