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 */
}
Every programming language has a built-in random function. In JavaScript, it's Math.random
:
function rollDice() {
return Math.random();
}
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
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
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?
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);
}
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);
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);
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 ;)
Top comments (1)
Hi great but..
always a dice can be rol 1 to MAX sides them
min = 1 always soo
function rollDice(sides) {
return (1-1) + Math.ceil(Math.random() * (sides-1+ 1))
}
Converting the expresion more simple
function rollDice(sides) {
return Math.ceil(Math.random() * sides)
}
rollDice(6)
rollDice(10)
rollDice(12)
rollDice(20)
rollDice(100)
if you want several dices !!
several call to the function.. good day!!
But the floor function its the base so depends what you want to be. simple easy or mor exactly case