Wil Wheaton's Dice

D&D is awesome. And Critical Role does an excellent job demonstrating that awesomeness. Witness exhibit A:

But it has also come to my attention that some who role dice are afflicted. Much like in economic life where some have a lot and others have a little, some people consistently roll high and others don't. Case in point, Wil Wheaton, exhibit B:

Many people just call this luck (or the lack of it) and leave it at that. In which case, poor Mr. Wheaton has been tragically cursed. Others just chalk it up to the nature of randomness. Somewhere in the universe, there is an alien who has rolled many dice, but always rolls the exact same number. Likely? No. Probable? Yes. And with a sample size as large as the universe, it's a certainty. So is Wil forever cursed by by an old gypsy woman? Or is he just a sad victim of a statistical inevitability?

Or is there a secret third option? Maybe software engineering and data science can ferret out some illusive juju-creative action the universe has never told us about. Maybe Mr. Wheaton's Curse has to do with the color of his bedroom walls or the ratio of the size of his dinner table over how often he washes his hands.

Is that hypothesis insane? Yes it is!
Is it also an excuse to learn more about software engineering? Yes it is!

Part 1: The Random Number Calculator

JavaScript has a random method inside its Math object which can easily be turned into a simulated dice roll.

console.log(Math.ceil(Math.random()*6)  

That will give results like rolling a die. Want to roll two at once?

console.log(Math.ceil(Math.random()*6 + Math.ceil(Math.random()*6)  

need a d20?

console.log(Math.ceil(Math.random()*20)  

+2 modifier?

console.log((Math.ceil(Math.random()*20)+2)  

I could go on, but I already beat this example to death three minutes ago. Trouble is, Math.random() isn't truly random. Computers are deterministic. You put the same input in, you get the same output out. That's what makes computers useful. Math.random() is pseudorandom. It uses a seed number to start, then applies an algorithm to shuffle that number up and produce an apparently random number at the far end. It then follows that algorithm to generate another number and another. If you let it go long enough, you'd see there is a deterministic, utterly predictable pattern to the numbers generated.

That's probably why gamers find dice rolling programs so loathsome. It is not truly random, so it feels like cheating. Or at least not like rolling dice. To get true randomness, you need some random (read unpredictable) input, such as light from a digital camera lens or the decay of a given plutonium atom. Who needs dice when we got all this plutonium lying around anyway?

Thing is, rolling dice isn't truly random either. A dice roll is forever in the icy deterministic grip of Isaac Newton. Its just that there are so many variables it becomes impossible to predict. But Tomasz Kapitaniak,of the University of Lodz in Poland has done the science already.

Apparently the two biggest variables are what side is facing up, and how many times the die bounces on the table. How many times the die bounces on the table is a function of friction. Higher friction tables cause more bounces, which help mitigate the predictive effect of which die face was initially facing up. So when you leave your dice on the table with the most desired number facing up to "train the dice", that actually has an effect, but only when you pick them up to throw them.

Basically on a frictionless surface, the die will not bounce or roll at all. It will land on whatever side was facing up when it was thrown. On an infinitely frictive surface, the dice roll doesn't become random, but chaotic. Like Butterfly Effect chaotic, or dinosaurs escaping the park chaotic.

But since there is no such thing as an infinitely frictive table that produces a die which bounces an infinite number of times, die rolls can only approach true chaos. Forget about random.

So what a dice-rolling program should do is take into account

  1. The starting position,
  2. The spin of the die leaving the hand (if any), and:
  3. Then use chaos mathematics to reproduce the frictive effect of a die bouncing on a table to determine the results.

So that leaves us with a question: How good is your phone's accelerometer?

we could make an app that allowed the user to input the die's initial facing and combine that with data from the phone's accelerometer to add in the spin of the die leaving the hand. When the die is cast, it would fall onto the mathematical equivalent of a frictive surface, perhaps the coeficient of a die on velvet-covered wood, and could display the results. It would certainly be much more satisfying to shake your phone rather than to just tap a button, and it would much more accurately reflect a true die roll.

Part 2: Data Analytics

So we got a plan to get the dice roller up and running, but what about the Wheaton Dice Curse? What in the wild world of sports is it?!

Data science is on the job!

The first question is how many dimensions of correlated data do we want to store? The closer we get to infinity, the less likely it is we'll miss something. But what if the event is really really really really really far removed from thedie roll? What if it's a bunny scratching its head 36 days ago in Bristol? Or its an entangled phenomenon with a great galactic war in Andromeda? Or it's somehow reverse-caused by what Wil decides to have for breakfast three days from now? Obviously we can't really monitor everything.

Since surely we can't be serious, I suppose it would be acceptable, if unscientific, to allow the subject to elect what events to provide the program for each die roll they do. That way, they can at least know what is not making a difference. Lucky underwear? Opening umbrellas indoors? Talking at the theatre? Any event the player worries is affecting their dice rolls will be proven, negatively or positively, to correlate with their poor dice-rolling luck (or not). That would be of much greater value to a player than a program that tells them that the French and Indian War and what their work buddies say about them behind their back is the cause of their poor luck at dice.

We could store the elected information in an array that is automatically pushed-to whenever the player makes a roll. Then we'd pass that information to another program that associates the info with its phi coefficient. That's all very basic. It's outlined in Eloquent Javascript: Chapter 4.

/*calculates phi*/
function phi(table) {  
    return (table[3] * table[0] - table[2] * table[1]) /
            Math.sqrt((table[2] + table[3]) *
                     (table[0] + table[1]) *
                     (table[1] + table[3]) *
                     (table[0] + table[2]));
}
/*determines if a given event is present in a die roll.*/
function hasEvent(event, dieRoll) {  
    return dieRoll.events.indexOf(event) != -1;
}
/*turns a given event into an array that phi can process.
Loops though whole database. If hasEvent returns positive, indexes appropriately.*/  
function tableFor(event, journal) {  
    var table = [0, 0, 0, 0];
      for (var i = 0; i < journal.length; i++) {
        var dieRoll = journal[i], index = 0;
          if (hasEvent(event, dieRoll)) index += 1;
        if (dieRoll.wheaton) index += 2;
          table[index] += 1;
    }
      return table;
}
/*"phis" is the map (new database object that associates each event with its phi.)
loops though each die roll,  
loops though each event in a die roll,  
if the event is not yet in the new database object phis,  
it's phi is calculated by the phi function,  
both it and its phi are added to phis*/  
function gatherCorrelations(journal) {  
    var phis = {};
      for (var dieRoll = 0; dieRoll < journal.length; dieRoll++) {
    var events = journal[dieRoll].events;
        for (var i = 0; i < events.length; i++) {
            var event = events[i];
              if (!(event in phis))
                phis[event] = phi(tableFor(event, journal));
        }
    }
      return phis;
}

The app could then display the results on a separately tabbed display so as not to clutter the dice-roller itself.

And for the sake of having something else the player can affect, we'll have one built in event they can toggle on or off: A 1 to 10 scale of "How important is this roll to you?". Because everyone has felt the dice betray them in their moment of need.

With this app, we might finally answer the great question of our era: Is the Wheaton Dice Curse a distortion caused by our psychology and the way our brains remember things? Or is it really that old gypsy woman we blamed in our gawky teenage years?

Now with software engineering and data science, we can waste our time in ways never dreamt of before!