curriculum/challenges/english/blocks/review-algorithmic-thinking-by-building-a-dice-game/657dfeef78fe0364bd241d7f.md
If you go through six rounds of the game, you should see the alert show up with your final score. But when you dismiss the alert, you are able to keep playing for more rounds past the original six. To fix this, you will need to reset the game.
Declare a resetGame function to do so. Reset all of the listOfAllDice elements to display 0, update score and rolls to be 0, update round to be 1, set the totalScoreElement text to the user's total score, clear the score history by setting it to an empty string, set the rollsElement text to the number of rolls, and set the roundElement text to the current round. Finally, reset all of the radio buttons to their initial states.
Call this function after displaying the alert with the final score.
You should have a function called resetGame.
assert.isFunction(resetGame);
Your resetGame function should set both score and rolls to 0, and round to 1.
score = 20;
round = 5000;
rolls = 150;
resetGame();
assert.strictEqual(score, 0);
assert.strictEqual(round, 1);
assert.strictEqual(rolls, 0);
Your resetGame function should set each listOfAllDice element to have the text 0.
rollDice();
resetGame();
for (const element of listOfAllDice) {
assert.strictEqual(element.innerText, "0")
}
Your resetGame function should set the text of the totalScoreElement element to the current score.
score = 100;
resetGame();
assert.strictEqual(totalScoreElement.innerText, "0");
Your resetGame function should set the text of the roundElement element to the current round.
round = 100;
resetGame();
assert.strictEqual(roundElement.innerText, "1");
Your resetGame function should set all of the radio buttons to be unchecked and disabled.
rolls = 0;
resetGame();
for (const element of scoreInputs) {
assert.isTrue(element.disabled);
assert.isFalse(element.checked);
}
Your resetGame function should remove the text from the scoreSpans elements.
rolls = 0;
resetGame();
for (const element of scoreSpans) {
assert.strictEqual(element.innerText, "");
}
You should call your resetGame function after displaying the alert in your keepScoreBtn listener.
let called = false;
const oldReset = resetGame;
resetGame = () => {
called = true;
oldReset();
}
const messages = [];
const oldAlert = alert;
const oldWindow = window.alert;
alert = (msg) => {messages.push(msg)};
window.alert = (msg) => {messages.push(msg)};
rolls = 1;
round = 6;
rollDiceBtn.click();
document.querySelector('#none').click();
keepScoreBtn.click();
assert.lengthOf(messages, 0);
assert.isFalse(called);
await new Promise(resolve => setTimeout(resolve, 1000)).then(() => {
assert.lengthOf(messages, 1);
assert.isTrue(called);
resetGame = oldReset;
alert = oldAlert;
window.alert = oldWindow;
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Advanced Dice Game</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header>
<h1>Advanced Dice Game</h1>
<button class="btn" id="rules-btn" type="button">Show rules</button>
<div class="rules-container">
<h2>Rules</h2>
<ul>
<li>There are total of six rounds</li>
<li>You can only roll the dice three times per round</li>
<li>To start the game, roll the dice</li>
<li>
Then, choose from one of the selected scores or roll the dice again
</li>
<li>
If you choose a selected score, then you will move to the next round
</li>
<li>
If you decline to choose a selected score, then you can roll the
dice again two more times
</li>
</ul>
<h2 class="points">Points</h2>
<ul>
<li>Three of a kind: Sum of all five dice</li>
<li>Four of a kind: Sum of all five dice</li>
<li>Full house: Three of a kind and a pair - 25 points</li>
<li>
Small straight: Four of the dice have consecutive values - 30 points
</li>
<li>
Large straight: All five dice have consecutive values - 40 points
</li>
</ul>
</div>
</header>
<main>
<form id="game">
<div id="dice">
<div class="die"></div>
<div class="die"></div>
<div class="die"></div>
<div class="die"></div>
<div class="die"></div>
</div>
<p class="rounds-text">
<strong>Rolls:</strong> <span id="current-round-rolls">0</span> |
<strong>Round:</strong> <span id="current-round">1</span>
</p>
<div id="score-options">
<div>
<input type="radio" name="score-options" id="three-of-a-kind" value="three-of-a-kind" disabled />
<label for="three-of-a-kind">Three of a kind<span></span></label>
</div>
<div>
<input type="radio" name="score-options" id="four-of-a-kind" value="four-of-a-kind" disabled />
<label for="four-of-a-kind">Four of a kind<span></span></label>
</div>
<div>
<input type="radio" name="score-options" id="full-house" value="full-house" disabled />
<label for="full-house">Full house<span></span></label>
</div>
<div>
<input type="radio" name="score-options" id="small-straight" value="small-straight" disabled />
<label for="small-straight">Small straight<span></span></label>
</div>
<div>
<input type="radio" name="score-options" id="large-straight" value="large-straight" disabled />
<label for="large-straight">Large straight<span></span></label>
</div>
<div>
<input type="radio" name="score-options" id="none" value="none" disabled />
<label for="none">None of the above<span></span></label>
</div>
</div>
<button class="btn" id="keep-score-btn" type="button">
Keep the above selected score
</button>
<button class="btn" id="roll-dice-btn" type="button">
Roll the dice
</button>
</form>
<div id="scores">
<h3>Score history (Total score: <span id="total-score">0</span>)</h3>
<ol id="score-history"></ol>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--dark-grey: #1b1b32;
--light-grey: #f5f6f7;
--black: #000;
--white: #fff;
--grey: #3b3b4f;
--golden-yellow: #fecc4c;
--yellow: #ffcc4c;
--gold: #feac32;
--orange: #ffac33;
--dark-orange: #f89808;
}
body {
background-color: var(--dark-grey);
}
header {
color: var(--light-grey);
text-align: center;
}
h1 {
font-size: 2.5rem;
margin: 25px 0;
}
.rules-container {
display: none;
background-color: var(--light-grey);
color: var(--black);
width: 50%;
margin: 20px auto;
height: 300px;
border-radius: 10px;
overflow-y: scroll;
}
.rules-container ul {
list-style-type: none;
}
.points {
margin-top: 15px;
}
main {
background-color: var(--light-grey);
padding: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
gap: 1rem;
margin: auto;
justify-items: center;
width: 50%;
border-radius: 10px;
}
#dice {
display: flex;
justify-content: space-around;
margin-bottom: 15px;
}
.die {
width: 40px;
height: 40px;
text-align: center;
margin-right: 15px;
border: 4px solid var(--black);
padding: 10px;
}
.rounds-text {
text-align: center;
}
input[type="radio"]:disabled + label {
color: var(--grey);
}
#score-history {
margin-top: 15px;
text-align: center;
list-style-position: inside;
}
.btn {
cursor: pointer;
width: 200px;
margin: 10px 0 10px 0.5rem;
color: var(--black);
background-color: var(--gold);
background-image: linear-gradient(var(--golden-yellow), var(--orange));
border-color: var(--gold);
border-width: 3px;
}
.btn:hover:enabled {
background-image: linear-gradient(var(--yellow), var(--dark-orange));
}
@media (max-width: 992px) {
main {
width: 100%;
}
}
@media (max-width: 500px) {
.btn {
width: 120px;
}
}
const listOfAllDice = document.querySelectorAll(".die");
const scoreInputs = document.querySelectorAll("#score-options input");
const scoreSpans = document.querySelectorAll("#score-options span");
const roundElement = document.getElementById("current-round");
const rollsElement = document.getElementById("current-round-rolls");
const totalScoreElement = document.getElementById("total-score");
const scoreHistory = document.getElementById("score-history");
const rollDiceBtn = document.getElementById("roll-dice-btn");
const keepScoreBtn = document.getElementById("keep-score-btn");
const rulesContainer = document.querySelector(".rules-container");
const rulesBtn = document.getElementById("rules-btn");
let diceValuesArr = [];
let isModalShowing = false;
let score = 0;
let round = 1;
let rolls = 0;
const rollDice = () => {
diceValuesArr = [];
for (let i = 0; i < 5; i++) {
const randomDice = Math.floor(Math.random() * 6) + 1;
diceValuesArr.push(randomDice);
};
listOfAllDice.forEach((dice, index) => {
dice.textContent = diceValuesArr[index];
});
};
const updateStats = () => {
rollsElement.textContent = rolls;
roundElement.textContent = round;
};
const updateRadioOption = (index, score) => {
scoreInputs[index].disabled = false;
scoreInputs[index].value = score;
scoreSpans[index].textContent = `, score = ${score}`;
};
const updateScore = (selectedValue, achieved) => {
score += parseInt(selectedValue);
totalScoreElement.textContent = score;
scoreHistory.innerHTML += `<li>${achieved} : ${selectedValue}</li>`;
};
const getHighestDuplicates = (arr) => {
const counts = {};
for (const num of arr) {
if (counts[num]) {
counts[num]++;
} else {
counts[num] = 1;
}
}
let highestCount = 0;
for (const num of arr) {
const count = counts[num];
if (count >= 3 && count > highestCount) {
highestCount = count;
}
if (count >= 4 && count > highestCount) {
highestCount = count;
}
}
const sumOfAllDice = arr.reduce((a, b) => a + b, 0);
if (highestCount >= 4) {
updateRadioOption(1, sumOfAllDice);
}
if (highestCount >= 3) {
updateRadioOption(0, sumOfAllDice);
}
updateRadioOption(5, 0);
};
const resetRadioOptions = () => {
scoreInputs.forEach((input) => {
input.disabled = true;
input.checked = false;
});
scoreSpans.forEach((span) => {
span.textContent = "";
});
};
--fcc-editable-region--
rollDiceBtn.addEventListener("click", () => {
if (rolls === 3) {
alert("You have made three rolls this round. Please select a score.");
} else {
rolls++;
resetRadioOptions();
rollDice();
updateStats();
getHighestDuplicates(diceValuesArr);
}
});
rulesBtn.addEventListener("click", () => {
isModalShowing = !isModalShowing;
if (isModalShowing) {
rulesBtn.textContent = "Hide rules";
rulesContainer.style.display = "block";
} else {
rulesBtn.textContent = "Show rules";
rulesContainer.style.display = "none";
}
});
keepScoreBtn.addEventListener("click", () => {
let selectedValue;
let achieved;
for (const radioButton of scoreInputs) {
if (radioButton.checked) {
selectedValue = radioButton.value;
achieved = radioButton.id;
break;
}
}
if (selectedValue) {
rolls = 0;
round++;
updateStats();
resetRadioOptions();
updateScore(selectedValue, achieved);
if (round > 6) {
setTimeout(() => {
alert(`Game Over! Your total score is ${score}`);
}, 500);
}
} else {
alert("Please select an option or roll the dice");
}
});
--fcc-editable-region--