How to roll a dice in JavaScript?

rocambille

Romain Guillemot

Posted on August 3, 2019

How to roll a dice in JavaScript?

Let's build the ultimate dice step by step.

Last update: May 11, 2022

Math.random() as a basis

A dice is a tool providing a random integer each time you roll it. Something like that:

function rollDice() {
  return /* some randomly generated number */
}
Enter fullscreen mode Exit fullscreen mode

Every programming language has a built-in random function. In JavaScript, it's Math.random:

function rollDice() {
  return Math.random();
}
Enter fullscreen mode Exit fullscreen mode

That’s a good start: returning a random number. Remember Math.random is not “random enough” for serious things like cryptography, or casino games — read about Crypto.getRandomValues if that’s your business. Math.random is fair enough to roll a dice with friends. Let’s try it:

>> function rollDice() {
     return Math.random();
   }
>> rollDice();
<- 0.7367823644188911
Enter fullscreen mode Exit fullscreen mode

This 0.7367823644188911 is not really what we wanted… According to documentation, Math.random returns a decimal number between 0 (inclusive) and 1 (exclusive). For a 6-sided dice, we need an integer from 1 to 6. As a first guess, you may multiply by 6:

>> function rollDice() {
     return Math.random() * 6;
   }
>> rollDice();
<- 4.3380209914241235
Enter fullscreen mode Exit fullscreen mode

So we would have a random decimal number between 0 (inclusive) and 6 (exclusive). So far, so good. Next step would be to get integer values:

  • If 0 ≤ Math.random() * 6 < 1, return 1
  • If 1 ≤ Math.random() * 6 < 2, return 2
  • If 2 ≤ Math.random() * 6 < 3, return 3
  • If 3 ≤ Math.random() * 6 < 4, return 4
  • If 4 ≤ Math.random() * 6 < 5, return 5
  • If 5 ≤ Math.random() * 6 < 6, return 6

This can be done using Math.floor. Let's try again — with a for-loop to console.log multiple rolls:

>> function rollDice() {
     return Math.floor(Math.random() * 6);
   }
>> for(let i = 0; i < 5; i++) console.log(rollDice());
   5
   1
   4
   2
   0 // WTF?
Enter fullscreen mode Exit fullscreen mode

Once again, not exactly what we wanted... What we get here is:

  • If 0 ≤ Math.floor(Math.random() * 6) < 1, return 0. Not 1.
  • If 1 ≤ Math.floor(Math.random() * 6) < 2, return 1. Not 2.
  • If 2 ≤ Math.floor(Math.random() * 6) < 3, return 2. Not 3.
  • If 3 ≤ Math.floor(Math.random() * 6) < 4, return 3. Not 4.
  • If 4 ≤ Math.floor(Math.random() * 6) < 5, return 4. Not 5.
  • If 5 ≤ Math.floor(Math.random() * 6) < 6, return 5. Not 6.

To get the wanted result with Math.floor, we will have to add 1 before returning:

function rollDice() {
  return 1 + Math.floor(Math.random() * 6);
}
Enter fullscreen mode Exit fullscreen mode

Now we have a function to simulate our 6-sided dice :)

Yes, but… What if we want a 4-, 8-, 12- or 20-sided one?

No big deal: you can change the magic number 6 in the code for a parameter, passing the maximum value for your dice. Something like this:

function rollDice(max) {
  return 1 + Math.floor(Math.random() * max);
}

const rollDice4 = () => rollDice(4);
const rollDice6 = () => rollDice(6);
const rollDice8 = () => rollDice(8);
const rollDice12 = () => rollDice(12);
const rollDice20 = () => rollDice(20);
Enter fullscreen mode Exit fullscreen mode

The ultimate dice

I was once inspired by a vision: “The Ultimate Display” by Ivan E. Sutherland, 1965. Among others, I like this quote:

There is no reason why the objects displayed by a computer have to follow the ordinary rules of physical reality with which we are familiar.

We used a parameter to replace the number of sides of our dice. Why not removing the other magic number? This ugly 1 may become an other parameter:

function rollDice(min, max) {
  return min + Math.floor(Math.random() * (max - min + 1));
}

const rollDice4 = () => rollDice(1, 4);
const rollDice6 = () => rollDice(1, 6);
const rollDice8 = () => rollDice(1, 8);
const rollDice12 = () => rollDice(1, 12);
const rollDice20 = () => rollDice(1, 20);
const rollSomeUltimateDice = () => rollDice(42, 42);
Enter fullscreen mode Exit fullscreen mode

This final version allows to simulate a dice which is not starting at 1. Moreover the max allows to simulate a uniform fair dice beyond “the ordinary rules of physical reality”. Imagine a 7-sided one. You can mimic your favorite dice game following its ordinary rules. But if you can imagine one, roll a dice which would never exist in reality ;)

💖 💪 🙅 🚩
rocambille
Romain Guillemot

Posted on August 3, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

How to roll a dice in JavaScript?
javascript How to roll a dice in JavaScript?

August 3, 2019