## DEV Community is a community of 718,999 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Romain Guillemot

Posted on • Originally published at Medium on

# How to roll a dice in JavaScript?

## TL;DR

Use existing tools like — among others — boardgame.io or DiceApi ;)

## I want to understand how it works

Ok. Let’s start by defining the need: we want a function which returns a random number to simulate a dice. Something like this:

``````function rollDice() {
return /* some randomly generated number */
}
``````

As far as I know, every programming language has a built-in random function. In JavaScript, this would lead to Math.random:

``````function rollDice() {
return Math.random()
}
``````

That’s a good start: returning a random number. Be aware that 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 ≤ x < 1, return 1
• If 1 ≤ x < 2, return 2
• If 2 ≤ x < 3, return 3
• If 3 ≤ x < 4, return 4
• If 4 ≤ x < 5, return 5
• If 5 ≤ x < 6, return 6

This can be done using Math.ceil — and a for-loop to console.log multiple rolls:

``````>> function rollDice() {
return Math.ceil(Math.random()*6)
}
>> for(let i = 0; i < 5; i++) console.log(rollDice())
1
4
5
3
6
``````

Or using Math.floor:

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

Same, but different. This would change the returned value as follows:

• If 0 ≤ x < 1, return 0
• If 1 ≤ x < 2, return 1
• If 2 ≤ x < 3, return 2
• If 3 ≤ x < 4, return 3
• If 4 ≤ x < 5, return 4
• If 5 ≤ x < 6, return 5

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

``````function rollDice() {
return 1 + Math.floor(Math.random()*6)
}
``````

So why using Math.floor instead of Math.ceil? Let’s see later. 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)
``````

Now we are here, 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)
``````

Note that the Math.ceil version for this would be:

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

Math.floor looks cleaner to me now, but feel free to pick the one you prefer ;)

#### 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.

The final code with the min 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. It’s ok, really. But if you can imagine one, roll a dice which would never exist in reality ;)
{"ft_lang_label":"__label__en","ft_lang_prob":0.71187574,"math_prob":0.9539466,"size":4034,"snap":"2021-43-2021-49","text_gpt3_token_len":1150,"char_repetition_ratio":0.1841191,"word_repetition_ratio":0.12162162,"special_character_ratio":0.3279623,"punctuation_ratio":0.14805825,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.99184185,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-10-21T15:37:46Z\",\"WARC-Record-ID\":\"<urn:uuid:a3f03e5a-fe37-496f-80a5-f9e41011dcef>\",\"Content-Length\":\"108171\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:7ae6159a-4179-4842-98f4-190e296aa837>\",\"WARC-Concurrent-To\":\"<urn:uuid:70958d4a-a5fb-4380-a3e1-01ceef7dd2a2>\",\"WARC-IP-Address\":\"151.101.66.217\",\"WARC-Target-URI\":\"https://dev.to/rocambille/how-to-roll-a-dice-in-javascript-51j0\",\"WARC-Payload-Digest\":\"sha1:5PNZ7LJHMRPE7GLHZSX2JQWWQWKSBPZ7\",\"WARC-Block-Digest\":\"sha1:LNU2NS4YIRH32HH3OQ7YWFBMCRTJ2XKK\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-43/CC-MAIN-2021-43_segments_1634323585424.97_warc_CC-MAIN-20211021133500-20211021163500-00417.warc.gz\"}"}