Dice Rolling Program

aaronmccollum profile image Aaron McCollum ・1 min read

Recently I started playing a game of Dungeons and Dragons with friends, and the first night I noticed I lacked the various sets of dice you need to play. My wife ordered a few sets, however I realized this was a great chance to put some of my HTML/CSS skills to the test with some JavaScript I recently learned.

On a Saturday morning, I got up early, slammed a few cups of coffee, and got to work. I wrote out the HTML and basic CSS first, since I'm a visual person and it helps to get a basic design down first. Then I went to work and created several functions for each type of dice. Lastly, I created a delete function to clear the board.

What do you think? Below are a few links:

A few updates I want to make soon:

  • Using less "ids" and more "classes" in HTML
  • Updating functions with ES6 shortcuts
  • Using "let" and "const" instead of var

If you have any tips or recommendations, let me know!

Posted on by:

aaronmccollum profile

Aaron McCollum


Customer success manager by day | Developer by night | @mccollumaarons on Twitter | Here at DEV to connect with other developers


markdown guide

You repeat yourself a lot. :)

The following technique may help avoid that.

const d = (sides) =>
  () => Math.ceil(Math.random() * sides);

const d20 = d(20);
const d12 = d(12);


Here d is a function which generates parameterized functions by using lexical closure.


You don't need to have a function that returns another function. You can simplify it to this:

function d(sides) {
  return Math.floor(Math.random() * sides + 1);

And use it with this:


Mind blown. Thank you all! I'm just now getting into ES6 and shorthand functions etc. I just love how there are ways to do in 10 lines what I did in ~50-60 lines. Incredible.

I'll be referencing this when I update the code in the next few weeks. Thank you both!


That's true, but his code wants to call functions directly.

Also, why are you adding 1 and then flooring?

I am adding one because Math.random() returns a float between 0 and 1, but it never includes 1, so you could never get 20 without adding 1.

Because some dice don't have zero while other's do. So we would need to switch on different dice.

But you're always adding one, so you'll never get zero ...

Exactly. We would remove that but we would need to switch between Math.ceil and Math.floor.

Making a function more complex in order to make it simpler to do something the function does not do is not very sensible. :)

What if we just did something like this:

function d(sides, hasZero = false) {
  return hasZero ? Math.ceil(Math.random() * sides) : Math.floor(Math.random() * sides);

If you want to generate integers in a range, you might as well just do that.

But the first thing to check are the requirements for this use case.

I believe that none of these dice include zero. :)


Great job! It looks like the other commenters beat me to it as far as suggestions since I was also thinking of ways to have code that is more DRY (Don't Repeat Yourself). Overall, I love seeing you go from idea to useful app! If you do end up writing a function that lets you pass the sides as an argument, you could add a feature so that the user can enter a custom sided die. Good luck!