Replace design with least amount of votes - javascript

I have a voting based system using javascript and local storage to save the designs & votes. I'd like a way to replace the design with the least amount of votes.
Currently I'm prepending a clone of the design to the start of the DOM, which obviously pushes the votes out of order and leaves me with more than 6 designs in the gallery.
Also I'm not sure of the logic if two designs have the same amount of votes?
Any hep would be appreciated.
Codepen here: https://codepen.io/fuzzyduck/pen/jOpzwXp
//variables for tracking votes
let voteVal1 = Number(localStorage.getItem("voteVal1"))
let voteVal2 = Number(localStorage.getItem("voteVal2"))
let voteVal3 = Number(localStorage.getItem("voteVal3"))
let voteVal4 = Number(localStorage.getItem("voteVal4"))
let voteVal5 = Number(localStorage.getItem("voteVal5"))
let voteVal6 = Number(localStorage.getItem("voteVal6"))
//log votes on load
console.log("Votes for 1: " +voteVal1)
console.log("Votes for 2: " +voteVal2)
console.log("Votes for 3: " +voteVal3)
console.log("Votes for 4: " +voteVal4)
console.log("Votes for 5: " +voteVal5)
console.log("Votes for 6: " +voteVal6)
//display votes on load
$(".voteVal1").html(voteVal1)
$(".voteVal2").html(voteVal2)
$(".voteVal3").html(voteVal3)
$(".voteVal4").html(voteVal4)
$(".voteVal5").html(voteVal5)
$(".voteVal6").html(voteVal6)
//increase votes
$(".btn1").on("click", function () {
localStorage.setItem("voteVal1", ++voteVal1)
$(".voteVal1").html(voteVal1)
})
$(".btn2").on("click", function () {
localStorage.setItem("voteVal2", ++voteVal2)
$(".voteVal2").html(voteVal2)
})
$(".btn3").on("click", function () {
localStorage.setItem("voteVal3", ++voteVal3)
$(".voteVal3").html(voteVal3)
})
$(".btn4").on("click", function () {
localStorage.setItem("voteVal4", ++voteVal4)
$(".voteVal4").html(voteVal4)
})
$(".btn5").on("click", function () {
localStorage.setItem("voteVal5", ++voteVal5)
$(".voteVal5").html(voteVal5)
})
$(".btn6").on("click", function () {
localStorage.setItem("voteVal6", ++voteVal6)
$(".voteVal6").html(voteVal6)
})
$(".resetAllVotes").on("click", function () {
localStorage.setItem("voteVal1", 0)
$(".voteVal1").html(0)
localStorage.setItem("voteVal2", 0)
$(".voteVal2").html(0)
localStorage.setItem("voteVal3", 0)
$(".voteVal3").html(0)
localStorage.setItem("voteVal4", 0)
$(".voteVal4").html(0)
localStorage.setItem("voteVal5", 0)
$(".voteVal5").html(0)
localStorage.setItem("voteVal6", 0)
$(".voteVal6").html(0)
})
//set colours on load
$(".container div").each(function(index) {
$(this).removeClass().addClass(localStorage.getItem(String(index))).addClass("circle")
})
//change colours
$(".btnred").on("click", function () {
$("#main").removeClass().addClass("red")
localStorage.setItem('ClassName', 'red')
})
$(".btnblue").on("click", function () {
$("#main").removeClass().addClass("blue")
localStorage.setItem('ClassName', 'blue')
})
$(".btnpurple").on("click", function () {
$("#main").removeClass().addClass("purple")
localStorage.setItem('ClassName', 'purple')
})
$(".clone").on("click", function () {
//the below has already been created in v1 - this is just for testing
$("#main").clone().removeClass("main").prependTo(".container")
$(".container div").each(function(index) {
localStorage.setItem(index, this.className)
})
//remove design with least votes (this is where the fun begins)
voting();
})
function voting(){
//new design will currently pre-pend to top left - but it should replace the design with the lowest score
//we then need to reset the voteVal to zero on the new design
//check which the lowest score (what if they have the same score?)
let pos1Check = [voteVal2,voteVal3,voteVal4,voteVal5,voteVal6];
if(voteVal1 > Math.min.apply(null, pos1Check)) {
console.log("Pos1: higher");
} else {
console.log("Pos1: lower");
}
//if pos2 fails we can remove it as it likely to have to least votes
let pos2Check = [voteVal1,voteVal3,voteVal4,voteVal5,voteVal6];
if(voteVal2 > Math.min.apply(null, pos2Check)) {
console.log("Pos2: higher");
} else {
console.log("Pos2: lower");
}
let pos3Check = [voteVal1,voteVal2,voteVal4,voteVal5,voteVal6];
if(voteVal3 > Math.min.apply(null, pos3Check)) {
console.log("Pos3: higher");
} else {
console.log("Pos3: lower");
}
let pos4Check = [voteVal1,voteVal2,voteVal3,voteVal5,voteVal6];
if(voteVal4 > Math.min.apply(null, pos4Check)) {
console.log("Pos4: higher");
} else {
console.log("Pos4: lower");
}
let pos5Check = [voteVal1,voteVal2,voteVal3,voteVal4,voteVal6];
if(voteVal5 > Math.min.apply(null, pos5Check)) {
console.log("Pos5: higher");
} else {
console.log("Pos5: lower");
}
let pos6Check = [voteVal1,voteVal2,voteVal3,voteVal4,voteVal5];
if(voteVal6 > Math.min.apply(null, pos6Check)) {
console.log("Pos6: higher");
} else {
console.log("Pos6: lower");
}
}

Related

Memory game with javascript

I have a small problem that could ruin the game. Once you click a card you need to search for the other card with the same picture right? but the problem is you can also double click and it will think you found the other card. Anyone know how o solf this problem?
const cards = document.querySelectorAll(".cards .card");
cards.forEach((card) => {
card.addEventListener("click", () => {
card.classList.add("clicked");
if (counter === 0) {
firstSelection = card.getAttribute("meme");
counter++;
} else {
secondSelection = card.getAttribute("meme");
counter = 0;
if (firstSelection === secondSelection) {
const correctCards = document.querySelectorAll(".card[meme='" + firstSelection + "']");
score.innerHTML = parseInt(score.innerHTML) + 1
if (score.innerHTML >= 8)
correctCards[0].classList.add("checked");
correctCards[0].classList.remove("clicked");
correctCards[1].classList.add("checked");
correctCards[1].classList.remove("clicked");
} else {
const incorrectCards = document.querySelectorAll(".card.clicked");
incorrectCards[0].classList.add("red");
incorrectCards[1].classList.add("red");
setTimeout(() => {
incorrectCards[0].classList.remove("red");
incorrectCards[0].classList.remove("clicked");
incorrectCards[1].classList.remove("red");
incorrectCards[1].classList.remove("clicked");
}, 600);
}
}
});
});
You can set 2 global vars firstClickedCard and secondClickedCard, and on click, assign the card element (event.currentTarget) to these variables. Then on second click, check if (secondClickedCard === firstClickedCard) before any of your other logic, and reject the click event if this is true.
This should verify if the actual clicked element (not just the meme attribute) are the same or not.
Note: this is untested, and would be easier to verify if your question included a minimal, reproducible example.
const cards = document.querySelectorAll(".cards .card");
var firstClickedCard;
var secondClickedCard;
cards.forEach((card) => {
card.addEventListener("click", (e) => {
card.classList.add("clicked");
if (counter === 0) {
firstClickedCard = e.currentTarget;
firstSelection = card.getAttribute("meme");
counter++;
} else {
secondClickedCard = e.currentTarget;
// reject this click
if (secondClickedCard === firstClickedCard) {
secondClickedCard = null;
return false;
}
secondSelection = card.getAttribute("meme");
counter = 0;
if (firstSelection === secondSelection) {
const correctCards = document.querySelectorAll(".card[meme='" + firstSelection + "']");
score.innerHTML = parseInt(score.innerHTML) + 1
if (score.innerHTML >= 8)
correctCards[0].classList.add("checked");
correctCards[0].classList.remove("clicked");
correctCards[1].classList.add("checked");
correctCards[1].classList.remove("clicked");
} else {
const incorrectCards = document.querySelectorAll(".card.clicked");
incorrectCards[0].classList.add("red");
incorrectCards[1].classList.add("red");
setTimeout(() => {
incorrectCards[0].classList.remove("red");
incorrectCards[0].classList.remove("clicked");
incorrectCards[1].classList.remove("red");
incorrectCards[1].classList.remove("clicked");
}, 600);
}
}
});
});
Although there is a double click event (dblclick), it is not supported by all browsers. The way around this is to test for double clicks within your click event handlers and use a timer function (to see if two clicks happened within a select amount of time). I use 300ms for the timer, but you may have to play around with that a bit.
const cards = document.querySelectorAll(".cards .card");
let clickCount = 0;
cards.forEach((card) => {
card.addEventListener("click", () => {
clickCount ++;
if (clickCount == 1) {
clickTimer = setTimeout(() => {
clickCount = 0;
//single click functionality here
card.classList.add("clicked");
if (counter === 0) {
firstSelection = card.getAttribute("meme");
counter++;
} else {
secondSelection = card.getAttribute("meme");
counter = 0;
if (firstSelection === secondSelection) {
const correctCards = document.querySelectorAll(".card[meme='" + firstSelection + "']");
score.innerHTML = parseInt(score.innerHTML) + 1
if (score.innerHTML >= 8)
correctCards[0].classList.add("checked");
correctCards[0].classList.remove("clicked");
correctCards[1].classList.add("checked");
correctCards[1].classList.remove("clicked");
} else {
const incorrectCards = document.querySelectorAll(".card.clicked");
incorrectCards[0].classList.add("red");
incorrectCards[1].classList.add("red");
setTimeout(() => {
incorrectCards[0].classList.remove("red");
incorrectCards[0].classList.remove("clicked");
incorrectCards[1].classList.remove("red");
incorrectCards[1].classList.remove("clicked");
}, 600);
}
}
}, 300);
} else if (clickCount == 2) {
clearTimeout(clickTimer);
clickCount = 0;
console.log("This was a double click!");
}
});
});

trying to access number variable outside the function in jQuery

Creating Stars rating system and I want to access the rating number and perform an action based on that. How can I access the number variable outside my click function?
$(document).ready(function () {
$(".li").mouseover(function () {
var current = $(this);
$(".li").each(function (index) {
$(this).addClass("hovered-stars");
if (index == current.index()) {
return false;
}
})
})
$(".li").mouseleave(function () {
$(this).removeClass("hovered-stars");
})
$(".li").click(function () {
$(".li").removeClass("clicked");
$(".hovered-stars").addClass("clicked");
var number = $(".clicked").length;
$("#message").html("You rated " + number + " Stars");
})
console.log(number);
})
Currently cannot print number variable outside click event listener
you need to declare the number variable outside the click function and then re-assign the value inside click function
$(document).ready(function () {
var number=0;
$(".li").mouseover(function () {
var current = $(this);
$(".li").each(function (index) {
$(this).addClass("hovered-stars");
if (index == current.index()) {
return false;
}
})
})
$(".li").mouseleave(function () {
$(this).removeClass("hovered-stars");
})
$(".li").click(function () {
$(".li").removeClass("clicked");
$(".hovered-stars").addClass("clicked");
number = $(".clicked").length;
$("#message").html("You rated " + number + " Stars");
})
console.log(number);
})

Can someone please assist with a JS function for var length

i am trying to display a modal based on a number of matched cards in a memory game.
i have already set var to be
let matchedCards = document.querySelectorAll('.match');
and then checking if matchedCards.length == 4 display a a modal (function) but I am unable to even enter that function for some reason.
// function to intialise game
function initGame() {
//set initial timer value
timer.innerHTML = '0 mins 0 secs';
//set initial star rating
for (var i = 0; i < stars.length; i++) {
stars[i].style.color = "#FFD700";
stars[i].style.visibility = "visible";
}
//deck selection and populating with generated card
let deck = document.querySelector('.deck');
let cardHTML = shuffle(cards).map(function(card) {
return generatedCard(card);
});
deck.innerHTML = cardHTML.join('');
allCards = document.querySelectorAll('.card');
//card function
allCards.forEach(function(card) {
card.addEventListener('click', function(e) {
openCards.push(card);
card.classList.add('open', 'show', 'disabled');
// setting move counter and matched/unmatched cards
if (openCards.length === 2) {
movesCounter();
if (openCards[0].dataset.card === openCards[1].dataset.card) {
matched();
} else {
unmatched();
}
} else {
allMatched();
}
})
});
};
//function for all matched
function allMatched() {
let matchedCards = document.querySelectorAll('.match');
if (matchedCards.length === 4) {
console.log(fourcards);
congratulations();
}
}
// match the 2 cards that are open if they are of the same type
function matched() {
openCards[0].classList.add("match", "disabled");
openCards[1].classList.add("match", "disabled");
openCards = [];
}
expecting to see the congrats modal popup if there are 4 matched cards on the deck.

setting a localstorage high score and displaying it

I have a tetris game that I am trying to finish but saving the high score after a game is over is causing me some issues. When the game ends, if the score is higher than what was previously saved as a highscore, it is supposed to save that new score as the high score locally and display that new highscore. I can not figure out why this is not happening. Below are the three different areas of my code that pertain to the high score. Any help would be appreciated.
creates the menu on the side of the game
<div id="tetris">
<div id="menu">
<p id="start">Press Space to Play.</p>
<p><canvas id="upcoming"></canvas></p>
<p>score <span id="score">00000</span></p>
<p>rows <span id="rows">0</span></p>
<p>high score <span id="highscore">0</span></p>
</div>
<canvas id="canvas">
Sorry, this example cannot be run because your browser does not support the <canvas> element
</canvas>
sets the high score when the game is over
var highscore = localStorage.getItem("highscore");
if (playing == false){
if(highscore !==null){
if(vscore > highscore) {
localStorage.setItem("highscore", vscore);
}
}
else{
localStorage.setItem("highscore", vscore);
}
}
else{
null;
}
updates the scores to display them
function play() { hide('start'); reset(); playing = true; }
function lose() { show('start'); setVisualScore(); playing = false; }
function setVisualScore(n) { vscore = n || score; invalidateScore(); }
function setScore(n) { score = n; setVisualScore(n); }
function addScore(n) { score = score + n; }
function clearScore() { setScore(0); }
function clearRows() { setRows(0); }
function setRows(n) { rows = n; step = Math.max(speed.min, speed.start - (speed.decrement*rows)); invalidateRows(); }
function addRows(n) { setRows(rows + n); }
function setHighScore(n) { highscore = n; }
function addHighScore(n) { setHighScore(highscore); }
function getBlock(x,y) { return (blocks && blocks[x] ? blocks[x][y] : null); }
function setBlock(x,y,type) { blocks[x] = blocks[x] || []; blocks[x][y] = type; invalidate(); }
function clearBlocks() { blocks = []; invalidate(); }
function clearActions() { actions = []; }
function setCurrentPiece(piece) { current = piece || randomPiece(); invalidate(); }
function setNextPiece(piece) { next = piece || randomPiece(); invalidateNext(); }
function reset() {
dt = 0;
clearActions();
clearBlocks();
clearRows();
clearScore();
setCurrentPiece(next);
setNextPiece();
}
function update(idt) {
if (playing) {
if (vscore < score)
setVisualScore(vscore + 1);
handle(actions.shift());
dt = dt + idt;
if (dt > step) {
dt = dt - step;
drop();
}
}
}
I can add the full game code if needed but these are the three areas that directly pertain to the high score issue.
Try the following:
function update(idt) {
if (playing) {
if (vscore < score)
setVisualScore(vscore + 1);
handle(actions.shift());
dt = dt + idt;
if (dt > step) {
dt = dt - step;
drop();
}
// Add the following to update the highscore while playing.
if (score > highscore) {
setHighScore(score);
}
}
}
setHighScore = (score) => {
// update highscore
highscore = score;
// update it visually?
document.getElementById('highscore').text = highscore;
}
Then somewhere you'd want a check once the game is over -- I'd assume immediately where you set the playing boolean to false.
if (playing === false){
if(vscore > highscore) {
// For future games.
localStorage.setItem("highscore", vscore);
}
}
edit :
I'm typing this on my phone, so apologies if format is wonky.
See example : https://codepen.io/anon/pen/pVEJJW

How to change cases in a switch statement once one case condition is met?

I'm trying to figure out how to switch between cases in Javascript/jQuery. I'm creating a dice game where the player needs to roll the dice until they finish the "Phase". Once they finish the "Phase" they will move onto the next "Phase" and any previous "Phases" won't interfere with the current "Phase". There will be several different "Phases" where they start at "Phase 1" and work down to "Phase 2" and so on until the last phase. Is there any way I can work down the "Phases"? I'm trying a switch statement here with no success. If a switch statement won't do the job, what will?
//Start of Dice Code
var die1Array = [];
var die2Array = [];
var die3Array = [];
var die1 = function() {
var roll1 = Math.floor(Math.random() * 6) + 1;
if(roll1 === 1) {
die1Array.push(1);
}
else if(roll1 === 2) {
die1Array.push(2);
}
else if(roll1 === 3) {
die1Array.push(3);
}
else if(roll1 === 4) {
die1Array.push(4);
}
else if(roll1 === 5) {
die1Array.push(5);
}
else if(roll1 === 6) {
die1Array.push(6);
}
};
var die2 = function() {
var roll2 = Math.floor(Math.random() * 6) + 1;
if(roll2 === 1) {
die2Array.push(1);
}
else if(roll2 === 2) {
die2Array.push(2);
}
else if(roll2 === 3) {
die2Array.push(3);
}
else if(roll2 === 4) {
die2Array.push(4);
}
else if(roll2 === 5) {
die2Array.push(5);
}
else if(roll2 === 6) {
die2Array.push(6);
}
};
var die3 = function() {
var roll3 = Math.floor(Math.random() * 6) + 1;
if(roll3 === 1) {
die3Array.push(1);
}
else if(roll3 === 2) {
die3Array.push(2);
}
else if(roll3 === 3) {
die3Array.push(3);
}
else if(roll3 === 4) {
die3Array.push(4);
}
else if(roll3 === 5) {
die3Array.push(5);
}
else if(roll3 === 6) {
die3Array.push(6);
}
};
//End of Dice Code
var main = function() {
$("#roll").on("click", die1);
$("#roll").on("click", die2);
$("#roll").on("click", die3);
$("#roll").on("click", die4);
$("#roll").on("click", die5);
$("#roll").on("click", die6);
//Where I want to switch between cases.
//Once Phase 1's condition (the if statement) is met, I want to switch to Phase 2.
var lvls = 1;
switch(lvls) {
case 1:
alert("Phase 1");
$("#submit").click(function() {
if((die1Array.slice(-1)=="1"||die2Array.slice(-1)=="1"||die3Array.slice(-1)=="1")&&(die1Array.slice(-1)=="2"||die2Array.slice(-1)=="2"||die3Array.slice(-1)=="2")&&(die1Array.slice(-1)=="3"||die2Array.slice(-1)=="3"||die3Array.slice(-1)=="3")) {
alert("Completed Phase 1: Straight of 3");
lvls = 2;
return lvls;
}
else {
alert("Phase 1: Straight of 3. Not Complete. Try again.");
};
});
break;
case 2:
alert("Phase 2");
//Phase 2's code
break;
//Additional cases/Phases would go here.
default:
};
};
$(document).ready(main);
In your die# function you could just push the values without the if else part.
var die1 = function () {
var roll1 = Math.floor(Math.random() * 6) + 1;
die1Array.push(roll1);
}
Or more general:
var die = function (dieArray) {
dieArray.push(Math.floor(Math.random() * 6) + 1);
}
Using:
die(die1Array);
die(die2Array);
die(die3Array);
...
The issue of your current swithc is that you bind an event handler function inside a case.
If you want that event handler work only in a particular state, you should set a state variable to save the current state and check this variable in the handler function.
var main = function () {
var diceState = 1;
$("#submit").click(function() {
if (diceState === 1) {
// do something
}
});
switch(lvls) {
case 1:
diceState = 1;
break;
case 2:
diceState = 2;
break;
}
The other problem you have is that you set the value of lvls to 1 in the main function and so you will have only 1 case, the other changes of lvls will have no effect at all, even you call main again.
If you call main more than one time, then you have the problem you're continuosly binding event onsubmit, so each time you submit the form, the function handler is called many times.
You should move the switch statement in a different function, passing the state variable as parameter, and call each time you want to change the state.
So here an example:
// Should be in same scope of the function
// or an attribute of an object to be passed by reference.
var diceState;
var changeState = function (state) {
switch(state) {
case 1:
diceState = 1;
break;
....
default:
throw new Error("State " + state + " not supported");
}
}
And is a good practice to use the default case to handle unexpected values.
Here a suggestion on how to change your main function:
var main = function() {
var lvls;
$("#roll").on("click", die1);
$("#roll").on("click", die2);
$("#roll").on("click", die3);
$("#roll").on("click", die4);
$("#roll").on("click", die5);
$("#roll").on("click", die6);
var changeState = function (state) {
switch(state) {
case 1:
alert("Phase 1");
lvls = state;
break;
case 2:
alert("Phase 2");
//Phase 2's code
lvls = state;
break;
//Additional cases/Phases would go here.
default:
};
}
// bind the event handler
$("#submit").click(function() {
if((die1Array.slice(-1)=="1"||die2Array.slice(-1)=="1"||die3Array.slice(-1)=="1")&&(die1Array.slice(-1)=="2"||die2Array.slice(-1)=="2"||die3Array.slice(-1)=="2")&&(die1Array.slice(-1)=="3"||die2Array.slice(-1)=="3"||die3Array.slice(-1)=="3")) {
alert("Completed Phase 1: Straight of 3");
changeState(2);
// you could not return the vaue here!
// return lvls;
}
else {
alert("Phase 1: Straight of 3. Not Complete. Try again.");
};
});
changeState(1);
};
Before addressing your question I want to mention your if/else statements:
if(roll1 === 1) {
die1Array.push(1);
}
else if(roll1 === 2) {
die1Array.push(2);
}
If you're going to put the value of roll1 into die1Array regardless of what the value is, why are you checking it first every time? Just do a die1Array.push(roll1); and call it a day.
I don't think you even want a switch statement here at all. What are you hoping to achieve with a switch statement?
The logic of your code is essentially this:
var main = function() {
// onclick stuff
lvls = 1
switch(lvls){}
}
This is going to immediately go into this switch statement with the hard value of 1 you force immediately before it, thus always hitting the first case.
The logic of this seems like it would be better suited to calling various functions. Maybe a function for phaseTwo(){...} but a switch statement is primarily used to check the state of an item at a specific point, not for tracking the state over time.
Here is some working ES6 code you may find useful.
It defines the names and the verification functions for each of the phases in an array. The roll function performs the random generation of the 5 dices (could be any number) a few times, so to give some animation, and then calls back, providing the value of each of the dice.
A global lvl variable is then used to find and execute the correct verification function. If this passes, the lvl is incremented:
const dieFaces = [null,'⚀','⚁','⚂','⚃','⚄','⚅'];
const DICE_COUNT = 5;
var lvl = 0;
var phases = [
{
descr: 'Phase 1: Pair',
test: function (counts) {
return counts.some( count => count > 1 );
}
},
{
descr: 'Phase 2: Three of a Kind',
test: function (counts) {
return counts.some( count => count > 2 );
}
},
{
descr: 'Phase 3: Full House',
test: function (counts) {
return counts.some( count => count > 2 ) &&
counts.filter( count => count > 1 ).length > 1;
}
},
{
descr: 'Phase 4: Small Straight',
test: function (counts) {
return counts.map( count => count>0 ).join('').indexOf('1111') > -1;
}
},
{
descr: 'Phase 5: Large Straight',
test: function (counts) {
return counts.map( count => count>0 ).join('').indexOf('11111') > -1;
}
},
{
descr: 'Phase 6: Four of a Kind',
test: function (counts) {
return counts.some( count => count > 3 );
}
}
];
function roll(callback, rolling = 20) {
let faces = [];
let dice = [];
for (let i = 0; i < DICE_COUNT; i++) {
let die = Math.floor(Math.random() * 6) + 1;
dice.push(die);
faces.push(dieFaces[die]);
}
$('#dice').html(faces.join(' '));
if (!rolling) return callback(dice);
setTimeout(roll.bind(null, callback, rolling-1), 50);
}
$("#roll").on("click", function () {
$('#result').text("");
roll(function (dice) {
var acc = dice.map( die => 0 );
dice.forEach( die => ++acc[die] );
if (phases[lvl].test(acc)) {
$('#result').text("Completed " + phases[lvl].descr);
lvl++;
$('#phase').text(phases[lvl].descr);
} else {
$('#result').text("Try again");
}
});
});
$('#phase').text(phases[0].descr);
#dice { font-size: 40px }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="phase"></div>
<button id="roll">Roll</button>
<div id="dice"></div>
<div id="result"></div>

Categories

Resources