Streaming live at 10am (PST) # Display a set of number calculate by rules

Hi everyone,
I’m trying to build a D&D like site. There is a very important step which is generate their ability scores.

The D&D v5 rule use 4D6 for this step, which means throw four of the 6 side dices, discard the lowest number and add the other 3 as one valid number, IF shows two ones, reroll.

I wonder how can I repeat this 6 times to get 6 results with one click as one set of their ability.

I have been looking all over the place but can deal with this. Please help!

Joshua

You’ll need to add some custom code to make this work. Something like this should get you moving in the right direction!

``````// generate a random number between min and max
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

// role 4, 6-sided die. if the result has more than two 1s in it,
// re-role until it doesn't.
// the result array is sorted so the lowest number is in result
function roll() {
let result = [];
do {
result = Array.from({ length: 4 }, () => randomNumber(1, 6));
} while ((result.find((num) => num === 1) || []).length >= 2);
return result.sort();
}

// role for 6 different DND attributes and collect the values
// in result
function main() {
const result = ["str", "con", "dex", "int", "wis", "chm"].reduce(
(memo, attr) => {
memo[attr] = roll()
.slice(1) // slice off the number at 0 since it is the lowest
.reduce((memo, item) => memo + item);
return memo;
},
{}
);
console.log(result);
}

main();
``````

You would want to call `main` or whatever you want to call it from a click event on a button. I’m not sure what your plans are after this but this should give you enough to get started with!

2 Likes

Hi @arb,
First of all I need to admit, I don’t know JS, but I tried really hard to learn it, and I’m still learning.
I can see the result in console, this is exactly I needed, thank you so much.
I tried to modify the code to the way I want it, and I couldn’t even to make it show at the front, so I want to ask you about it.

My goals are:
1> Player can use this button get 6 attributes and display in 6 text blocks so players can assign them.
2> This is one of the steps to create their character, so this step is in a form, when user submit this form I need to know their results.

``````<script>
//Button click event to run the function
\$('.button.roll-6-attributes').click(()=>{

// generate a random number between min and max
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

// role 4, 6-sided die. if the result has more than two 1s in it,
// re-role until it doesn't.
// the result array is sorted so the lowest number is in result
function roll() {
let result = [];
do {
result = Array.from({ length: 4 }, () => randomNumber(1, 6));
} while ((result.find((num) => num === 1) || []).length >= 2);
return result.sort();
}

// role for 6 different DND attributes and collect the values
// in result
function main() {
const result = ["str", "con", "dex", "int", "wis", "chm"].reduce(
(memo, attr) => {
memo[attr] = roll()
.slice(1) // slice off the number at 0 since it is the lowest
.reduce((memo, item) => memo + item);
return memo;
},
{}
);
// Output to a text box
console.log(result);
document.querySelector('.6-attributes').innerHTML=(result);
}
main();
});
</script>``````

I had the solution after all.
Credits to @arb .

``````// Associate an event listener to the button id
document.getElementById("roll-6-attributes").addEventListener("click", main);
// generate a random number between min and max
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

// role 4, 6-sided die. if the result has more than two 1s in it,
// re-role until it doesn't.
// the result array is sorted so the lowest number is in result
function roll() {
let result = [];
do {
result = Array.from({ length: 4 }, () => randomNumber(1, 6));
} while ((result.find((num) => num === 1) || []).length >= 2);
return result.sort();
}
// role for 6 different DND attributes and collect the values
// in result
function main() {
const result = ["str", "con", "dex", "int", "wis", "chm"].reduce(
(memo, attr) => {
memo[attr] = roll()
.slice(1) // slice off the number at 0 since it is the lowest
.reduce((memo, item) => memo + item);
return memo;
},
{}
);
//Output to console
console.log(result);
//Output to a text box have a specific class associate to
document.querySelector(".attributes").innerHTML = JSON.stringify(result);
}``````