mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-01 08:05:25 -05:00
chore: cleanup dice game flow and tests (#52555)
Co-authored-by: Kristofer Koishigawa <scissorsneedfoodtoo@gmail.com>
This commit is contained in:
@@ -53,172 +53,312 @@
|
||||
"title": "Step 10"
|
||||
},
|
||||
{
|
||||
"id": "657a1b8d2ff90ce56dc9c8dc",
|
||||
"id": "657c7e53fa2354011942a466",
|
||||
"title": "Step 11"
|
||||
},
|
||||
{
|
||||
"id": "657a1d7a4da888e7acfbf9fd",
|
||||
"id": "657c82663a6b6a043f6c4b45",
|
||||
"title": "Step 12"
|
||||
},
|
||||
{
|
||||
"id": "657a218c34af9ceb661de044",
|
||||
"id": "657c8ebc64810f0d603d6773",
|
||||
"title": "Step 13"
|
||||
},
|
||||
{
|
||||
"id": "649efc2e07fbb2012b69c5d4",
|
||||
"id": "657c91ad5028770fc68d6116",
|
||||
"title": "Step 14"
|
||||
},
|
||||
{
|
||||
"id": "649f02123109440198becab7",
|
||||
"id": "657c9b39c73e91177e95596a",
|
||||
"title": "Step 15"
|
||||
},
|
||||
{
|
||||
"id": "649f03f6f661fb01d98fcfd1",
|
||||
"id": "657c9dbff0fee6196fa8dcff",
|
||||
"title": "Step 16"
|
||||
},
|
||||
{
|
||||
"id": "649f0e6e081b80023d1b4fab",
|
||||
"id": "657c9f0af0e3d61abde1c005",
|
||||
"title": "Step 17"
|
||||
},
|
||||
{
|
||||
"id": "649f0fb16b7e27027526f4da",
|
||||
"id": "657ca019f086e81bf05e7f95",
|
||||
"title": "Step 18"
|
||||
},
|
||||
{
|
||||
"id": "649f12c7c84ffb02b0fc7563",
|
||||
"id": "657ca0cb6dc5e71cb5615141",
|
||||
"title": "Step 19"
|
||||
},
|
||||
{
|
||||
"id": "657a34809aba0502807b1937",
|
||||
"id": "657ca4ec988f8420247eeb54",
|
||||
"title": "Step 20"
|
||||
},
|
||||
{
|
||||
"id": "657a3c9ace5a8d086cf2cd2f",
|
||||
"id": "657ca764afcc5221ee01f1a9",
|
||||
"title": "Step 21"
|
||||
},
|
||||
{
|
||||
"id": "657a3ee8aa19b00ac3f78816",
|
||||
"id": "657ca813b0908a230e3eb488",
|
||||
"title": "Step 22"
|
||||
},
|
||||
{
|
||||
"id": "64a1b343d112ec024cf2025f",
|
||||
"id": "657ca92f931f5c243418c2f9",
|
||||
"title": "Step 23"
|
||||
},
|
||||
{
|
||||
"id": "64a1b48cbd1c3102840cf715",
|
||||
"id": "657caa69db80ef25862b1b17",
|
||||
"title": "Step 24"
|
||||
},
|
||||
{
|
||||
"id": "64a1b5a282d4b502ad83043a",
|
||||
"id": "657cacdc21264127cc50cd7a",
|
||||
"title": "Step 25"
|
||||
},
|
||||
{
|
||||
"id": "64a1b6a63614f002dce978ed",
|
||||
"id": "657cad74fb5301287c572167",
|
||||
"title": "Step 26"
|
||||
},
|
||||
{
|
||||
"id": "64a2391ae5a6b3022bc1ce6e",
|
||||
"id": "657caf204c0d672a35411c31",
|
||||
"title": "Step 27"
|
||||
},
|
||||
{
|
||||
"id": "64a23a46c4dc89026019f8e4",
|
||||
"id": "657cc7c8bc1a5340a011f838",
|
||||
"title": "Step 28"
|
||||
},
|
||||
{
|
||||
"id": "64a24015fe4fbd02a16cbbe7",
|
||||
"id": "657cca458baba042a1b4eef9",
|
||||
"title": "Step 29"
|
||||
},
|
||||
{
|
||||
"id": "64a7bf43e7f374013d88b4e6",
|
||||
"id": "657ccb8022b59543d2e391b7",
|
||||
"title": "Step 30"
|
||||
},
|
||||
{
|
||||
"id": "64a7c1a836c47c016f5d9c99",
|
||||
"id": "657cd762ea9e6a47c459ee8b",
|
||||
"title": "Step 31"
|
||||
},
|
||||
{
|
||||
"id": "64a7c453d3ddbe01a194ddc1",
|
||||
"id": "657cf2b586b3495a69394d7c",
|
||||
"title": "Step 32"
|
||||
},
|
||||
{
|
||||
"id": "64a7cc96491a05022098d7b0",
|
||||
"id": "657cf677438e705eab9fd1f9",
|
||||
"title": "Step 33"
|
||||
},
|
||||
{
|
||||
"id": "64ae4d469444a0014fb1dc80",
|
||||
"id": "657cfad68610a4654bb171f4",
|
||||
"title": "Step 34"
|
||||
},
|
||||
{
|
||||
"id": "64ae500423fa16018a83fa31",
|
||||
"id": "657d009db786a869aa68acfa",
|
||||
"title": "Step 35"
|
||||
},
|
||||
{
|
||||
"id": "64ae5180ff093301b90147cc",
|
||||
"id": "657d02cbb9c5416bef6a5023",
|
||||
"title": "Step 36"
|
||||
},
|
||||
{
|
||||
"id": "64ae530773cd7001ebacc6c1",
|
||||
"id": "657d068a236fb16f00183e2b",
|
||||
"title": "Step 37"
|
||||
},
|
||||
{
|
||||
"id": "64ae54048b468302209dd977",
|
||||
"id": "657d0a5bf57d5c721d5e82e4",
|
||||
"title": "Step 38"
|
||||
},
|
||||
{
|
||||
"id": "64ae550d9fdb40025e5857ae",
|
||||
"id": "657d0b35f0d14873018d02fa",
|
||||
"title": "Step 39"
|
||||
},
|
||||
{
|
||||
"id": "64ae561e7f4217029684cefd",
|
||||
"id": "657d0de92782dd7532563649",
|
||||
"title": "Step 40"
|
||||
},
|
||||
{
|
||||
"id": "64ae57bf4eac6002c85af0e0",
|
||||
"id": "657d0ff4bcc54e76bd79651b",
|
||||
"title": "Step 41"
|
||||
},
|
||||
{
|
||||
"id": "64ae5d8d2ae28b030cfd035e",
|
||||
"id": "657d10e12efdd577d27597ff",
|
||||
"title": "Step 42"
|
||||
},
|
||||
{
|
||||
"id": "64ae6a43e797ab035c56d88b",
|
||||
"id": "657d14f730b1797b03e1175b",
|
||||
"title": "Step 43"
|
||||
},
|
||||
{
|
||||
"id": "64ae6aff1af3780391f3a0a0",
|
||||
"id": "657d16efbc877d7d0d0aec1a",
|
||||
"title": "Step 44"
|
||||
},
|
||||
{
|
||||
"id": "64ae70794c6760043f553998",
|
||||
"id": "657d17da1d6da97e2c0af800",
|
||||
"title": "Step 45"
|
||||
},
|
||||
{
|
||||
"id": "64ae722962105404772b7618",
|
||||
"id": "657d1af3a6a54784a82a1e6d",
|
||||
"title": "Step 46"
|
||||
},
|
||||
{
|
||||
"id": "64ae74510e6aed04a975f72f",
|
||||
"id": "657d1d52d574588677347c7f",
|
||||
"title": "Step 47"
|
||||
},
|
||||
{
|
||||
"id": "64b457bb4cd0e2013d839c92",
|
||||
"id": "657d301f80931609b9a5d110",
|
||||
"title": "Step 48"
|
||||
},
|
||||
{
|
||||
"id": "64b45a195557d801660f07d5",
|
||||
"id": "657d368b5115bc137f38220d",
|
||||
"title": "Step 49"
|
||||
},
|
||||
{
|
||||
"id": "64b45d46f718ff01988c51ad",
|
||||
"id": "657d374ef92a36145abdd215",
|
||||
"title": "Step 50"
|
||||
},
|
||||
{
|
||||
"id": "64b8c2130652b4013da1cc8a",
|
||||
"id": "657d397542d1a2162407ac39",
|
||||
"title": "Step 51"
|
||||
},
|
||||
{
|
||||
"id": "64b8c3f6f4dfc701661fab4f",
|
||||
"id": "657d3ab710745d17697c633a",
|
||||
"title": "Step 52"
|
||||
},
|
||||
{
|
||||
"id": "657d459868330c1e1da6bd49",
|
||||
"title": "Step 53"
|
||||
},
|
||||
{
|
||||
"id": "657d491c439d642176fc2fc8",
|
||||
"title": "Step 54"
|
||||
},
|
||||
{
|
||||
"id": "657d4a7e2002f822c646204b",
|
||||
"title": "Step 55"
|
||||
},
|
||||
{
|
||||
"id": "657d4c910e9a5724886b9f92",
|
||||
"title": "Step 56"
|
||||
},
|
||||
{
|
||||
"id": "657d4d734e523a257125596b",
|
||||
"title": "Step 57"
|
||||
},
|
||||
{
|
||||
"id": "657d4eb2785e0d268dbd2ad2",
|
||||
"title": "Step 58"
|
||||
},
|
||||
{
|
||||
"id": "657d509785c2f12828d7196f",
|
||||
"title": "Step 59"
|
||||
},
|
||||
{
|
||||
"id": "657d535901979b2a4b2a345c",
|
||||
"title": "Step 60"
|
||||
},
|
||||
{
|
||||
"id": "657d552526c0d72beb57160f",
|
||||
"title": "Step 61"
|
||||
},
|
||||
{
|
||||
"id": "657dfc42adf7696260da54f1",
|
||||
"title": "Step 62"
|
||||
},
|
||||
{
|
||||
"id": "657dfeef78fe0364bd241d7f",
|
||||
"title": "Step 63"
|
||||
},
|
||||
{
|
||||
"id": "657e01b37d256166f84be8d5",
|
||||
"title": "Step 64"
|
||||
},
|
||||
{
|
||||
"id": "657e033dcf624668a1a6180b",
|
||||
"title": "Step 65"
|
||||
},
|
||||
{
|
||||
"id": "657e0485c9c0e469d6bc3ed1",
|
||||
"title": "Step 66"
|
||||
},
|
||||
{
|
||||
"id": "657e066025aa6c6b77f33a9b",
|
||||
"title": "Step 67"
|
||||
},
|
||||
{
|
||||
"id": "657e0846af6cff6cf9b792db",
|
||||
"title": "Step 68"
|
||||
},
|
||||
{
|
||||
"id": "657e09d4802a136e868a7f5e",
|
||||
"title": "Step 69"
|
||||
},
|
||||
{
|
||||
"id": "657e0c2c6a9d37705146f34d",
|
||||
"title": "Step 70"
|
||||
},
|
||||
{
|
||||
"id": "657e0f2a6cb19c72b8760be5",
|
||||
"title": "Step 71"
|
||||
},
|
||||
{
|
||||
"id": "657e13351e0232761a908609",
|
||||
"title": "Step 72"
|
||||
},
|
||||
{
|
||||
"id": "657e14fb165435777a597aea",
|
||||
"title": "Step 73"
|
||||
},
|
||||
{
|
||||
"id": "657e180ad0a77c79d8b4b82e",
|
||||
"title": "Step 74"
|
||||
},
|
||||
{
|
||||
"id": "657e18b58d9f6a7ac1544999",
|
||||
"title": "Step 75"
|
||||
},
|
||||
{
|
||||
"id": "657e1bfa4f1f5d7d5c14d43d",
|
||||
"title": "Step 76"
|
||||
},
|
||||
{
|
||||
"id": "657e21575e71e2822f3b0abd",
|
||||
"title": "Step 77"
|
||||
},
|
||||
{
|
||||
"id": "657e230500602983e01fff6e",
|
||||
"title": "Step 78"
|
||||
},
|
||||
{
|
||||
"id": "657e253cf2c01685ed84c1ee",
|
||||
"title": "Step 79"
|
||||
},
|
||||
{
|
||||
"id": "657e27774cb16b8810c18ba8",
|
||||
"title": "Step 80"
|
||||
},
|
||||
{
|
||||
"id": "657e2bac662a3c8f5801d550",
|
||||
"title": "Step 81"
|
||||
},
|
||||
{
|
||||
"id": "657e2d01d1a086908d3c9d32",
|
||||
"title": "Step 82"
|
||||
},
|
||||
{
|
||||
"id": "657e2e1f5fb69291b1294388",
|
||||
"title": "Step 83"
|
||||
},
|
||||
{
|
||||
"id": "657e2ecee9f60092c89338d9",
|
||||
"title": "Step 84"
|
||||
},
|
||||
{
|
||||
"id": "657e30e116d50c946b189925",
|
||||
"title": "Step 85"
|
||||
},
|
||||
{
|
||||
"id": "657e37e29b45c39a98482860",
|
||||
"title": "Step 86"
|
||||
},
|
||||
{
|
||||
"id": "657e390964da9f9bff8f3625",
|
||||
"title": "Step 87"
|
||||
}
|
||||
],
|
||||
"helpCategory": "JavaScript"
|
||||
|
||||
@@ -1,324 +0,0 @@
|
||||
---
|
||||
id: 64a1b343d112ec024cf2025f
|
||||
title: Step 23
|
||||
challengeType: 0
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next step is to add the functionality for allowing the user to toggle the display for the rules.
|
||||
|
||||
Start by adding an `addEventListener()` to the `rulesBtn` element. The `addEventListener()` should listen for a `click` event for the first argument and take in an empty arrow function for the second argument.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `addEventListener()` for your `rulesBtn` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /rulesBtn\.addEventListener\s*\(\s*.*\s*/);
|
||||
```
|
||||
|
||||
You should have a `click` event as the first argument to the `addEventListener` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /rulesBtn\.addEventListener\s*\(\s*('|"|`)\s*click\s*\1\s*/);
|
||||
```
|
||||
|
||||
You should have an arrow function as the second argument to the `addEventListener` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /rulesBtn\.addEventListener\s*\(\s*('|"|`)\s*click\s*\1\s*,\s*\(\s*[^)]*\)\s*=>/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,335 +0,0 @@
|
||||
---
|
||||
id: 64a1b5a282d4b502ad83043a
|
||||
title: Step 25
|
||||
challengeType: 0
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the rules are currently showing, then you will want the button text to say "Hide rules".
|
||||
|
||||
Create an `if` statement that checks the truthy value of the `isModalShowing` variable. Inside the `if` statement, add the `textContent` property on `rulesBtn` element and assign it the string value of `Hide Rules`.
|
||||
|
||||
Below that, update the `display` property on `rulesContainer` and set it to `block`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*.*\s*\)\s*{\s*.*\s*}\s*/);
|
||||
```
|
||||
|
||||
Your `if` statement should check if `isModalShowing` is truthy.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*isModalShowing\s*\)/);
|
||||
```
|
||||
|
||||
You should update the `textContent` property on `rulesBtn` to the string `Hide Rules`.
|
||||
|
||||
```js
|
||||
assert.match(code, /rulesBtn\.textContent\s*=\s*('|"|`)Hide Rules\1/);
|
||||
```
|
||||
|
||||
You should target the `display` property on `rulesContainer` and assign it the string value of `block`.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*?if\s*\(isModalShowing\)\s*{\s*.*?rulesContainer\.style\.display\s*=\s*['"]block['"]/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
});
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,330 +0,0 @@
|
||||
---
|
||||
id: 64a1b6a63614f002dce978ed
|
||||
title: Step 26
|
||||
challengeType: 0
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the modal is not showing then the button text should display as "Show rules" and the modal should be hidden.
|
||||
|
||||
Below your `if` statement, add an `else` statement. Inside your `else` statement, add the `textContent` property on `rulesBtn` and assign the string value of `Show Rules`.
|
||||
|
||||
Then, set the `display` property on `rulesContainer` and assign it the string value of `none`.
|
||||
|
||||
Test out your button and to see the rules toggle from shown to hidden.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should update the `textContent` property on `rulesBtn` to the string `Show Rules` inside an `else` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*.*?rulesBtn\.textContent\s*=\s*('|"|`)Show Rules\1/s);
|
||||
```
|
||||
|
||||
You should target the `display` property on `rulesContainer` and set it to `none` inside the `else` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*?else\s*{\s*.*?rulesContainer\.style\.display\s*=\s*['"]none['"]/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,358 +0,0 @@
|
||||
---
|
||||
id: 64a23a46c4dc89026019f8e4
|
||||
title: Step 28
|
||||
challengeType: 0
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To detect if the dice roll was a straight, you will first need to sort the numbers in ascending order.
|
||||
|
||||
Inside your `straightDetector` function, use the `sort` method on the `arr` parameter. For the callback function, pass in `a` and `b` for the parameters and `implicitly` return `a - b`.
|
||||
|
||||
Assign the entire result to a `const` named `sortNumbers`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable called `sortNumbers`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortNumbers\s*/);
|
||||
```
|
||||
|
||||
You should assign `arr` to `sortNumbers`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortNumbers\s*=\s*arr(.*)/);
|
||||
```
|
||||
|
||||
You should apply the `sort` method to the `arr` parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortNumbers\s*=\s*arr\.sort\(.*\);?/);
|
||||
```
|
||||
|
||||
You should pass `a` and `b` as parameters to the `sort` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortNumbers\s*=\s*(?:arr\.sort\(\s*function\s*\(\s*a\s*,\s*b\s*\)\s*{\s*return\s*a\s*-\s*b\s*;?\s*}\s*\)|arr\.sort\(\s*\(a,\s*b\)\s*=>\s*a\s*-\s*b\s*\));?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const rollDiceBtn = document.getElementById("roll-dice-btn");
|
||||
const rulesBtn = document.getElementById("rules-btn");
|
||||
const rulesContainer = document.querySelector(".rules-container");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
|
||||
let isModalShowing = false;
|
||||
|
||||
let diceValuesArr = [];
|
||||
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
let score = 0;
|
||||
let totalScore = 0;
|
||||
|
||||
function rollDice() {
|
||||
diceValuesArr = [];
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
let randomDice = Math.floor(Math.random() * 6) + 1;
|
||||
diceValuesArr.push(randomDice);
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateStats() {
|
||||
currentRoundRollsText.innerHTML = rolls;
|
||||
currentRoundText.innerHTML = round;
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
currentRoundRollsText.innerHTML = rolls;
|
||||
currentRoundText.innerHTML = round;
|
||||
}
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,347 +0,0 @@
|
||||
---
|
||||
id: 64a7c1a836c47c016f5d9c99
|
||||
title: Step 31
|
||||
challengeType: 0
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create a `const` variable named `smallStraightLogic` and store the string values `1234`, `2345` and `3456` in an array. This will be used to check if the user has rolled a small straight.
|
||||
|
||||
Similarly, create a `const` variable named `largeStraightLogic` and store the string values `12345` and `23456` in an array. This will be used to check if the user has rolled a large straight.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable named `smallStraightLogic`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+smallStraightLogic\s*=?\s*;?/);
|
||||
```
|
||||
|
||||
You should store the string values `1234`, `2345` and `3456` in an array and assign it to the `smallStraightLogic` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+smallStraightLogic\s*=?\s*\[\s*['"]1234['"]\s*,\s*['"]2345['"]\s*,\s*['"]3456['"]\s*\];?/);
|
||||
```
|
||||
|
||||
You should have a `const` variable named `largeStraightLogic`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+largeStraightLogic\s*/);
|
||||
```
|
||||
|
||||
You should store the string values `12345` and `23456` in an array and assign it to the `largeStraightLogic` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+largeStraightLogic\s*=?\s*\[\s*['"]12345['"]\s*,\s*['"]23456['"]\s*\];?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,340 +0,0 @@
|
||||
---
|
||||
id: 64ae4d469444a0014fb1dc80
|
||||
title: Step 34
|
||||
challengeType: 0
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, use the `optionNode` parameter to target the `scoreInputs` and set its `value` property to `score` parameter.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should target the `scoreInputs` using the `optionNode` parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\[\s*optionNode\s*\]/);
|
||||
```
|
||||
|
||||
You should set the `value` property of the `scoreInputs[optionNode]` to `score` the parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\[\s*optionNode\s*\]\.value\s*=\s*score/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert( "You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,365 +0,0 @@
|
||||
---
|
||||
id: 64ae550d9fdb40025e5857ae
|
||||
title: Step 39
|
||||
challengeType: 0
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You need to run the newly created `straightDetector` function to see the results on the display. To do this, create an arrow function named `findRollResult` and set the argument to `arr`. Then, call the function `straightDetector` with the argument of `arr`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `findRollResult` function.
|
||||
|
||||
```js
|
||||
assert.isFunction(findRollResult);
|
||||
```
|
||||
|
||||
Your `findRollResult` function should be an arrow function.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+findRollResult\s*=\s*\([\s\S]*\)\s*=>\s*{\s*[\s\S]*\s*};?/);
|
||||
```
|
||||
|
||||
Your `findRollResult` should have a parameter called `arr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /(const\s*findRollResult\s*=\s*\(arr\)\s*=>\s*{|function\s*findRollResult\s*\(arr\)\s*{)/);
|
||||
```
|
||||
|
||||
You should call the function `straightDetector` with the argument of `arr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*findRollResult\s*=\s*\(arr\)\s*=>\s*{\s*straightDetector\s*\(\s*arr\s*\);\s*};?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -11,7 +11,7 @@ In this project, you will learn algorithmic thinking by building a dice game. Th
|
||||
|
||||
The HTML and CSS have been provided for you. Feel free to explore them.
|
||||
|
||||
When you are ready, use the `querySelectorAll` method to target all elements with the `class` of `die`, and assign that to a constant called `listOfAllDice`.
|
||||
When you are ready, use the `querySelectorAll()` method to target all elements with the `class` of `die`, and assign that to a constant called `listOfAllDice`.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ The next step is to select all of the elements responsible for displaying the sc
|
||||
|
||||
Use the `querySelectorAll()` method to access all of the `input` elements inside the `#score-options` `div` element and assign that result to a constant called `scoreInputs`.
|
||||
|
||||
Then use the `querySelectorAll()` method to access all of the `span` elements inside the `#score-options` `div` element and assign that result to a constant called `scoreInputs`.
|
||||
Then use the `querySelectorAll()` method to access all of the `span` elements inside the `#score-options` `div` element and assign that result to a constant called `scoreSpans`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable named `scoreInputs`.
|
||||
You should use `const` to declare a variable named `scoreInputs`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+scoreInputs\s*/);
|
||||
@@ -33,7 +33,7 @@ You should target all of the `input` elements inside the `#score-options` `div`
|
||||
assert.match(code, /const\s+scoreInputs\s*=\s*document\.querySelectorAll\(\s*['"]#score-options\s+input['"]\s*\)/);
|
||||
```
|
||||
|
||||
You should declare a variable named `scoreSpans`.
|
||||
You should use `const` to declare a variable named `scoreSpans`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+scoreSpans\s*/);
|
||||
|
||||
@@ -15,7 +15,7 @@ Then, use `getElementById()` to access the element with the `id` of `current-rou
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a `const` variable named `currentRoundText`.
|
||||
You should use `const` to declare a variable named `currentRoundText`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*currentRoundText\s*/);
|
||||
@@ -27,7 +27,7 @@ You should use `document.getElementById()` to target the `current-round` element
|
||||
assert.match(code, /const\s*currentRoundText\s*=\s*document\.getElementById\s*\(\s*['"]current-round['"]\s*\)\s*;?/s);
|
||||
```
|
||||
|
||||
You should declare a `const` variable named `currentRoundRollsText`.
|
||||
You should use `const` to declare a variable named `currentRoundRollsText`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*currentRoundRollsText\s*/);
|
||||
|
||||
@@ -15,7 +15,7 @@ Then, use `getElementById()` to access the element with the `id` of `score-histo
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a `const` variable named `totalScoreText`.
|
||||
You should use `const` to declare a variable named `totalScoreText`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*totalScoreText\s*/);
|
||||
@@ -27,7 +27,7 @@ You should use `document.getElementById()` to target the `total-score` element a
|
||||
assert.match(code, /const\s*totalScoreText\s*=\s*document\.getElementById\s*\(\s*['"]total-score['"]\s*\)\s*;?/s);
|
||||
```
|
||||
|
||||
You should declare a `const` variable named `scoreHistory`.
|
||||
You should use `const` to declare a variable named `scoreHistory`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*scoreHistory\s*/);
|
||||
|
||||
@@ -7,7 +7,7 @@ dashedName: step-6
|
||||
|
||||
# --description--
|
||||
|
||||
Next, you will need access the container used to display the rules and the rules button element.
|
||||
Next, you will need to access the container responsible for displaying the rules. You will also need to access the button responsible for showing and hiding the rules.
|
||||
|
||||
Use `querySelector()` to access the element with the `class` of `rules-container` and assign that to a constant called `rulesContainer`.
|
||||
|
||||
@@ -21,7 +21,7 @@ You should use `const` to declare a variable called `rulesContainer`.
|
||||
assert.match(code, /const\s*rulesContainer\s*/);
|
||||
```
|
||||
|
||||
You should use `document.querySelector()` to target the `rules-container` element and assign it to your `rulesContainer` variable.
|
||||
You should use `document.querySelector()` to target the `.rules-container` element and assign it to your `rulesContainer` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*rulesContainer\s*=\s*document\.querySelector\s*\(\s*['"]\.rules\-container['"]\s*\)/);
|
||||
|
||||
@@ -7,7 +7,7 @@ dashedName: step-7
|
||||
|
||||
# --description--
|
||||
|
||||
When the user clicks on the "Show rules" button, they should be able to toggle between showing and hiding the game rules.
|
||||
When the user clicks on the `Show rules` button, they should be able to toggle between showing and hiding the game rules.
|
||||
|
||||
Use `let` to create a variable called `isModalShowing` and assign it the value of `false`.
|
||||
|
||||
|
||||
@@ -11,29 +11,17 @@ Throughout the game, you will need to keep track of the current score, total sco
|
||||
|
||||
Use `let` to declare three variables named `rolls`, `score`, and `totalScore` and set all of their values to the number `0`.
|
||||
|
||||
Then, use `let` to declare a variable named `round` and assign it the value `1`.
|
||||
Then, use `let` to declare a variable named `round` and assign it the number `1`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `let` to declare a variable named `round`.
|
||||
|
||||
```js
|
||||
assert.match(code, /let\s*round/);
|
||||
```
|
||||
|
||||
You should set the value of `round` to `1`.
|
||||
|
||||
```js
|
||||
assert.match(code, /round\s*=\s*1/);
|
||||
```
|
||||
|
||||
You should use `let` to declare a variable named `rolls`.
|
||||
|
||||
```js
|
||||
assert.match(code, /let\s*rolls/);
|
||||
```
|
||||
|
||||
You should set the value of `rolls` to `0`.
|
||||
You should assign the number `0` to your `rolls` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /rolls\s*=\s*0/);
|
||||
@@ -45,7 +33,7 @@ You should use `let` to declare a variable named `score`.
|
||||
assert.match(code, /let\s*score/);
|
||||
```
|
||||
|
||||
You should set the value of `score` to `0`.
|
||||
You should assign the number `0` to `score` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /score\s*=\s*0/);
|
||||
@@ -57,12 +45,24 @@ You should use `let` to declare a variable named `totalScore`.
|
||||
assert.match(code, /let\s*totalScore/);
|
||||
```
|
||||
|
||||
You should set the value of `totalScore` to `0`.
|
||||
You should assign the number `0` to your `totalScore` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /totalScore\s*=\s*0/);
|
||||
```
|
||||
|
||||
You should use `let` to declare a variable named `round`.
|
||||
|
||||
```js
|
||||
assert.match(code, /let\s*round/);
|
||||
```
|
||||
|
||||
You should assign the number `1` to your `round` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /round\s*=\s*1/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
@@ -7,22 +7,28 @@ dashedName: step-10
|
||||
|
||||
# --description--
|
||||
|
||||
Whenever the user rolls the dice, the dice display should update on the screen.
|
||||
When the user clicks on the `Show rules` button, the rules for the game should display on the screen. When they click on the button again, the rules should be hidden. In the next few steps, you will build out the toggle functionality to show and hide the rules.
|
||||
|
||||
Create an arrow function called `rollDice` that does not take in any parameters.
|
||||
Start by using the `addEventListener()` method on the `rulesBtn`. For the first argument, pass in a `click` event and for the second argument pass in an empty arrow function.
|
||||
|
||||
# --hints--
|
||||
|
||||
`rollDice` should be a function.
|
||||
You should use the `addEventListener()` method on the `rulesBtn`.
|
||||
|
||||
```js
|
||||
assert.isFunction(rollDice);
|
||||
assert.match(code, /rulesBtn\s*\.\s*addEventListener\s*\(/);
|
||||
```
|
||||
|
||||
`rollDice` should be an arrow function
|
||||
You should have a `click` event for the first argument of the `addEventListener()`.
|
||||
|
||||
```js
|
||||
assert.match(code, /\s*const\s+rollDice\s*=\s*\(\s*\)\s*=>\s*{\s*}\s*;?/);
|
||||
assert.match(code, /rulesBtn\.addEventListener\s*\(\s*('|"|`)\s*click\s*\1\s*/);
|
||||
```
|
||||
|
||||
You should have an empty arrow function for the second argument of the `addEventListener()`.
|
||||
|
||||
```js
|
||||
assert.match(code, /rulesBtn\.addEventListener\s*\(\s*('|"|`)\s*click\s*\1\s*,\s*\(\s*[^)]*\)\s*=>/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
---
|
||||
id: 657c7e53fa2354011942a466
|
||||
title: Step 11
|
||||
challengeType: 0
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Every time the user clicks on the rules button, the current boolean value for the `isModalShowing` variable should toggle between `true` and `false`.
|
||||
|
||||
Use the `logical NOT operator(!)` in front of your `isModalShowing` variable to invert the value and reassign that to the `isModalShowing` variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `logical NOT operator(!)` in front of your `isModalShowing` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /!\s*isModalShowing/);
|
||||
```
|
||||
|
||||
You should reassign the inverted `isModalShowing` value to `isModalShowing`.
|
||||
|
||||
```js
|
||||
assert.match(code, /^\s*isModalShowing\s*=\s*!\s*isModalShowing/m);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 0;
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
|
||||
--fcc-editable-region--
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
|
||||
});
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,301 @@
|
||||
---
|
||||
id: 657c82663a6b6a043f6c4b45
|
||||
title: Step 12
|
||||
challengeType: 0
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If `isModalShowing` is `true`, then you will need to show the rules and update the `rulesBtn` text.
|
||||
|
||||
Start by adding an `if` statement to check if `isModalShowing` is truthy. Inside your `if` statement, update the text content for the `rulesBtn` by assigning it the string value of `Hide Rules`.
|
||||
|
||||
Below that, update the `display` property for your `rulesContainer` by assigning it the string value of `block`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `if` statement to check if `isModalShowing` is truthy.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*isModalShowing\s*\)\s*{\s*[\s\S]*?\s*}\s*;?/);
|
||||
```
|
||||
|
||||
You should assign the string `Hide Rules` to `rulesBtn.textContent` inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*isModalShowing\s*\)\s*{\s*rulesBtn\.textContent\s*=\s*('|"|`)Hide Rules\1\s*;?\s*.*\s*}\s*;?/);
|
||||
```
|
||||
|
||||
You should assign the string `block` to `rulesContainer.style.display` inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*isModalShowing\s*\)\s*{\s*rulesBtn\.textContent\s*=\s*('|"|`)Hide Rules\1\s*;?[\s\S]*?rulesContainer\.style\.display\s*=\s*('|"|`)block\2[\s\S]*}\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 0;
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,307 @@
|
||||
---
|
||||
id: 657c8ebc64810f0d603d6773
|
||||
title: Step 13
|
||||
challengeType: 0
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If `isModalShowing` is `false`, then you will need to hide the rules and update the `rulesBtn` text.
|
||||
|
||||
Below your `if` statement, add an `else` clause. Inside your `else` clause, update the text content for the `rulesBtn` by assigning it the string value of `Show Rules`.
|
||||
|
||||
Below that, update the `display` property for your `rulesContainer` by assigning it the string value of `none`.
|
||||
|
||||
Now you should be able to toggle rules button and see the rules been shown and hidden.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*[\s\S]*?\s*}\s*;?/);
|
||||
```
|
||||
|
||||
You should assign the string `Show Rules` to `rulesBtn.textContent` inside your `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*rulesBtn\.textContent\s*=\s*('|"|`)Show Rules\1\s*;?\s*.*\s*}\s*;?/);
|
||||
```
|
||||
|
||||
You should assign the string `none` to `rulesContainer.style.display` inside your `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*rulesBtn\.textContent\s*=\s*('|"|`)Show Rules\1\s*;?[\s\S]*?rulesContainer\.style\.display\s*=\s*('|"|`)none\2[\s\S]*}\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 0;
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,294 @@
|
||||
---
|
||||
id: 657c91ad5028770fc68d6116
|
||||
title: Step 14
|
||||
challengeType: 0
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
When the user clicks on the `Roll the dice` button, five random die numbers should be generated and displayed on the screen. For the next few steps, you will build out this roll dice algorithm.
|
||||
|
||||
Start by creating an arrow function called `rollDice`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an arrow function called `rollDice`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+rollDice\s*=\s*\(\s*\)\s*=>\s*{\s*[\s\S]*}\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 0;
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,19 +1,19 @@
|
||||
---
|
||||
id: 657a1b8d2ff90ce56dc9c8dc
|
||||
title: Step 11
|
||||
id: 657c9b39c73e91177e95596a
|
||||
title: Step 15
|
||||
challengeType: 0
|
||||
dashedName: step-11
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
For each dice roll, you will need to clear out the previous dice values in the `diceValuesArr`.
|
||||
Each time the user rolls the dice, the list of previous dice values should be reset.
|
||||
|
||||
Inside the `rollDice` function, reassign an empty array to the `diceValuesArr` variable.
|
||||
Inside your `rollDice` function, reassign an empty array to your `diceValuesArr` variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should reassign an empty array to your `diceValuesArr` variable.
|
||||
You should reassign and empty array to your `diceValuesArr` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+rollDice\s*=\s*\(\s*\)\s*=>\s*{\s*diceValuesArr\s*=\s*\[\s*\]\s*;?/);
|
||||
@@ -282,4 +282,16 @@ const rollDice = () => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
id: 657a1d7a4da888e7acfbf9fd
|
||||
title: Step 12
|
||||
id: 657c9dbff0fee6196fa8dcff
|
||||
title: Step 16
|
||||
challengeType: 0
|
||||
dashedName: step-12
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
When the user rolls the dice, you will need to generate 5 random numbers representing each of the dice values.
|
||||
When the user rolls the dice, you will need to generate 5 random numbers representing each die value.
|
||||
|
||||
To start, create a `for` loop that will loop a total of 5 times.
|
||||
|
||||
@@ -295,10 +295,23 @@ let totalScore = 0;
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
|
||||
--fcc-editable-region--
|
||||
const rollDice = () => {
|
||||
diceValuesArr = [];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
id: 657a218c34af9ceb661de044
|
||||
title: Step 13
|
||||
id: 657c9f0af0e3d61abde1c005
|
||||
title: Step 17
|
||||
challengeType: 0
|
||||
dashedName: step-13
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
For each iteration of the `for` loop, you will need to generate a random number that represents one of the six possible values found on a dice.
|
||||
For each iteration of the `for` loop, you will need to generate a random number that represents one of the six possible values found on a die.
|
||||
|
||||
Use `Math.random()` to generate a random number ranging between 1 and 6 inclusive. Make sure to round that result down to the nearest whole integer. Then assign the entire result to a `const` variable called `randomDice`.
|
||||
Use `Math.random()` to generate a random number ranging between `1` and `6` inclusive. Make sure to round that result down to the nearest whole integer. Then assign the entire result to a `const` variable called `randomDice`.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -25,13 +25,13 @@ You should assign `Math.random()` to the variable named `randomDice`.
|
||||
assert.match(code, /const\s+randomDice\s*=\s*.*Math\.random\s*\(\s*\)\s*/);
|
||||
```
|
||||
|
||||
You should multiply `Math.random()` by 6.
|
||||
You should multiply `Math.random()` by the number `6`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+randomDice\s*=\s*.*Math\.random\s*\(\s*\)\s*\*\s*6\s*/);
|
||||
```
|
||||
|
||||
You should use `Math.floor` to round the result down to the nearest whole number.
|
||||
You should use `Math.floor()` to round the result down to the nearest whole number.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+randomDice\s*=\s*Math\.floor\s*\(\s*Math\.random\s*\(\s*\)\s*\*\s*6\s*\)\s*/);
|
||||
@@ -301,12 +301,25 @@ let totalScore = 0;
|
||||
let round = 1;
|
||||
let rolls = 0;
|
||||
|
||||
--fcc-editable-region--
|
||||
const rollDice = () => {
|
||||
diceValuesArr = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
|
||||
}
|
||||
for (let i = 0; i < 5; i++) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 649efc2e07fbb2012b69c5d4
|
||||
title: Step 14
|
||||
id: 657ca019f086e81bf05e7f95
|
||||
title: Step 18
|
||||
challengeType: 0
|
||||
dashedName: step-14
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -278,12 +278,23 @@ let rolls = 0;
|
||||
const rollDice = () => {
|
||||
diceValuesArr = [];
|
||||
|
||||
--fcc-editable-region--
|
||||
for (let i = 0; i < 5; i++) {
|
||||
--fcc-editable-region--
|
||||
const randomDice = Math.floor(Math.random() * 6) + 1;
|
||||
|
||||
}
|
||||
--fcc-editable-region--
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
id: 649f02123109440198becab7
|
||||
title: Step 15
|
||||
id: 657ca0cb6dc5e71cb5615141
|
||||
title: Step 19
|
||||
challengeType: 0
|
||||
dashedName: step-15
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next step is to update the text content for all five of the dice displaying on the screen.
|
||||
The next step is display the five random dice values on the screen.
|
||||
|
||||
Use the `forEach` method on the `listOfAllDice` variable to loop through each of the dice. For the callback function, pass in a `dice` and `index` parameter.
|
||||
Below your `for` loop, use the `forEach` method on the `listOfAllDice` variable to loop through each of the dice. For the callback function, use `dice` and `index` for the parameters.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -19,7 +19,7 @@ You should use a `forEach` loop on the `listOfAllDice` variable.
|
||||
assert.match(code, /listOfAllDice\.forEach\s*\(.*\)/);
|
||||
```
|
||||
|
||||
Your callback function should have a `dice` and `index` parameter. Don't forget the parenthesis around the parameters.
|
||||
Your callback function should take `dice` and `index` as parameters. Don't forget the parentheses around the parameters.
|
||||
|
||||
```js
|
||||
assert.match(code, /listOfAllDice\.forEach\s*\(\s*\(\s*dice\s*,\s*index\s*\)\s*=>\s*{/);
|
||||
@@ -289,11 +289,22 @@ const rollDice = () => {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const randomDice = Math.floor(Math.random() * 6) + 1;
|
||||
diceValuesArr.push(randomDice);
|
||||
}
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 649f03f6f661fb01d98fcfd1
|
||||
title: Step 16
|
||||
id: 657ca4ec988f8420247eeb54
|
||||
title: Step 20
|
||||
challengeType: 0
|
||||
dashedName: step-16
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -287,13 +287,24 @@ const rollDice = () => {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const randomDice = Math.floor(Math.random() * 6) + 1;
|
||||
diceValuesArr.push(randomDice);
|
||||
};
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
--fcc-editable-region--
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
}
|
||||
--fcc-editable-region--
|
||||
});
|
||||
};
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
id: 649f0e6e081b80023d1b4fab
|
||||
title: Step 17
|
||||
id: 657ca764afcc5221ee01f1a9
|
||||
title: Step 21
|
||||
challengeType: 0
|
||||
dashedName: step-17
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now it is time to test out the `rollDice` function.
|
||||
|
||||
Add an `addEventListener()` method on the `rollDiceBtn` element and pass in a click event for the first argument and an empty arrow function for the second argument.
|
||||
Add an `addEventListener()` method on the `rollDiceBtn` element and pass in a `click` event for the first argument and an empty arrow function for the second argument.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -25,7 +25,7 @@ You should have a click event for the first argument for the `addEventListener()
|
||||
assert.match(code, /rollDiceBtn\.addEventListener\s*\(\s*('|"|`)\s*click\s*\1\s*/);
|
||||
```
|
||||
|
||||
You should have an empty arrow function for the second argument for the `addEventListener` method.
|
||||
You should have an empty arrow function for the second argument for the `addEventListener()` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /rollDiceBtn\.addEventListener\s*\(\s*("|'|`)\s*click\s*\1,\s*\(\s*\)\s*=>\s*{\s*[\s\S]*\s*}\s*\);/);
|
||||
@@ -295,8 +295,8 @@ const rollDice = () => {
|
||||
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];
|
||||
});
|
||||
@@ -306,4 +306,15 @@ const rollDice = () => {
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,17 +1,17 @@
|
||||
---
|
||||
id: 649f0fb16b7e27027526f4da
|
||||
title: Step 18
|
||||
id: 657ca813b0908a230e3eb488
|
||||
title: Step 22
|
||||
challengeType: 0
|
||||
dashedName: step-18
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In the game, you are allowed to roll the dice a maximum of three times per round.
|
||||
For each round in the game, users are allowed to roll the dice a maximum of three times.
|
||||
|
||||
Inside your callback function, add an `if` statement to check if `rolls` is strictly equal to the number `3`.
|
||||
|
||||
If the condition is true, show an `alert()` method to display the message `You have made three rolls this round. Please select a score.`.
|
||||
If the condition is `true`, show an `alert()` to display the message `You have made three rolls this round. Please select a score.`.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -303,17 +303,28 @@ const rollDice = () => {
|
||||
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];
|
||||
});
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
--fcc-editable-region--
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,17 +1,17 @@
|
||||
---
|
||||
id: 649f12c7c84ffb02b0fc7563
|
||||
title: Step 19
|
||||
id: 657ca92f931f5c243418c2f9
|
||||
title: Step 23
|
||||
challengeType: 0
|
||||
dashedName: step-19
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the rolls limit has not been reached, then the user can still roll the dice.
|
||||
If the `rolls` limit has not been reached, then the user can still roll the dice in that round.
|
||||
|
||||
Add an `else` clause below your `if` statement. Inside the `else` clause, increment `rolls` by one and then call the `rollDice` function.
|
||||
|
||||
Click on the "Roll the dice" button and you should see 5 random die values show up on the screen.
|
||||
Now, you should be able to roll the dice and see 5 random die values show up on the screen.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -21,7 +21,7 @@ You should add have an `else` statement.
|
||||
assert.match(code, /else\s*{\s*[\s\S]*\s*}/);
|
||||
```
|
||||
|
||||
You should increment `rolls` by `1` inside your `else` clause.
|
||||
You should use the `++` operator to increment `rolls` by `1` inside your `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*rolls\s*\+\+\s*[^}]*}/);
|
||||
@@ -297,20 +297,31 @@ const rollDice = () => {
|
||||
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];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
}
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
id: 657a34809aba0502807b1937
|
||||
title: Step 20
|
||||
id: 657caa69db80ef25862b1b17
|
||||
title: Step 24
|
||||
challengeType: 0
|
||||
dashedName: step-20
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If you try to roll the dice, you probably noticed that the `rolls` and `round` count do not change. You will need to update the text content for both of those values.
|
||||
If you try to roll the dice a few times, you probably noticed that the `rolls` and `round` count do not change. To fix this, you will need to update the text content for both of those values.
|
||||
|
||||
Start by creating an arrow function called `updateStats` that does not take in any parameters.
|
||||
Start by creating an arrow function called `updateStats`.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -289,7 +289,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -309,4 +309,15 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 657a3c9ace5a8d086cf2cd2f
|
||||
title: Step 21
|
||||
id: 657cacdc21264127cc50cd7a
|
||||
title: Step 25
|
||||
challengeType: 0
|
||||
dashedName: step-21
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -301,7 +301,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -323,4 +323,15 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
id: 657a3ee8aa19b00ac3f78816
|
||||
title: Step 22
|
||||
id: 657cad74fb5301287c572167
|
||||
title: Step 26
|
||||
challengeType: 0
|
||||
dashedName: step-22
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To see the `round` and `rolls` values update on the screen, call your `updateStats` function inside the `else` clause.
|
||||
To see the `round` and `rolls` values update on the screen, call your `updateStats` function inside the `else` clause of the `rollDiceBtn` event listener.
|
||||
|
||||
Now try rolling the dice, and you should see the `rolls` value properly updating.
|
||||
Now you should be able to roll the dice a few times and see the values update.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -283,7 +283,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -295,7 +295,6 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
@@ -308,4 +307,15 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,34 +1,34 @@
|
||||
---
|
||||
id: 64a7c453d3ddbe01a194ddc1
|
||||
title: Step 32
|
||||
id: 657caf204c0d672a35411c31
|
||||
title: Step 27
|
||||
challengeType: 0
|
||||
dashedName: step-32
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next step is to build out the functionality for displaying the options to select a score.
|
||||
Each time you roll the dice, you could end up with a `"Three of a kind"`, `"Four of a kind"`, `"Full house"`, `"Straight"` or a random combination of numbers. Based on the outcome, you can make a selection and add points to your score.
|
||||
|
||||
Create an arrow function named `updateRadioOption` and pass in two parameters named `optionNode` and `score`.
|
||||
Start by creating an arrow function called `updateRadioOption` that takes `optionNode` and `score` as parameters.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a function named `updateRadioOption`.
|
||||
`updateRadioOption` should be a function.
|
||||
|
||||
```js
|
||||
assert.isFunction(updateRadioOption);
|
||||
```
|
||||
|
||||
Your `updateRadioOption` function should be an arrow function.
|
||||
You should use arrow syntax for the `updateRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+updateRadioOption\s*=\s*\(.*\)\s*=>\s*{\s*}\s*/)
|
||||
assert.match(code, /const\s+updateRadioOption\s*=\s*\(.*\)\s*=>\s*{\s*[\s\S]*};?/)
|
||||
```
|
||||
|
||||
Your `updateRadioOption` function should have two parameters named `optionNode` and `score`.
|
||||
Your `updateRadioOption` function should take `optionNode` and `score` as parameters.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+updateRadioOption\s*=\s*\(\s*optionNode\s*,\s*score\s*\)\s*=>\s*{\s*}\s*/)
|
||||
assert.match(code, /const\s+updateRadioOption\s*=\s*\(\s*optionNode\s*,\s*score\)\s*=>\s*{\s*[\s\S]*};?/)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -295,7 +295,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -311,15 +311,6 @@ const updateStats = () => {
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
}
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
@@ -341,5 +332,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,22 +1,20 @@
|
||||
---
|
||||
id: 64a1b48cbd1c3102840cf715
|
||||
title: Step 24
|
||||
id: 657cc7c8bc1a5340a011f838
|
||||
title: Step 28
|
||||
challengeType: 0
|
||||
dashedName: step-24
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In order to toggle the display modal, you will need to flip the boolean value for the `isModalShowing` variable.
|
||||
|
||||
Inside your callback function, use the `logical NOT operator` to invert the value of the `isModalShowing` boolean.
|
||||
To enable the radio buttons, you should set the `disabled` property on `scoreInputs[optionNode]` to `false`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `logical NOT operator(!)` to reassign the `isModalShowing` variable its inverted value.
|
||||
You should assign `false` to `scoreInputs[optionNode].disabled`.
|
||||
|
||||
```js
|
||||
assert.match(code, /isModalShowing\s*=\s*!\s*isModalShowing/);
|
||||
assert.match(code, /scoreInputs\[\s*optionNode\s*\]\.disabled\s*=\s*false/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -283,7 +281,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -295,6 +293,12 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
@@ -305,10 +309,15 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
|
||||
});
|
||||
--fcc-editable-region--
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,324 @@
|
||||
---
|
||||
id: 657cca458baba042a1b4eef9
|
||||
title: Step 29
|
||||
challengeType: 0
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, you will need to update the radio button's `value` to the current `score`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign the `score` variable to `scoreInputs[optionNode].value`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\[\s*optionNode\s*\]\.value\s*=\s*score/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 64a7bf43e7f374013d88b4e6
|
||||
id: 657ccb8022b59543d2e391b7
|
||||
title: Step 30
|
||||
challengeType: 0
|
||||
dashedName: step-30
|
||||
@@ -7,20 +7,14 @@ dashedName: step-30
|
||||
|
||||
# --description--
|
||||
|
||||
You will join all the elements in the `uniqueNumbers` array into a string and store it in a variable named `stringifyArray`. This will be used to check if the user has rolled a small straight or a large straight.
|
||||
To display the current score, update the text content for the `span` element next to the radio button to be the following template literal: `, score = ${score}`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable named `stringifyArray`.
|
||||
You should set the `textContent` property for `scoreSpans[optionNode]` to the following template literal: `, score = ${score}`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+stringifyArray\s*=?\s*;?/);
|
||||
```
|
||||
|
||||
You should assign `uniqueNumbers.join('')` to your `stringifyArray` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+stringifyArray\s*=?\s*uniqueNumbers\.join\(\s*['"]['"]\s*\);?/);
|
||||
assert.match(code, /scoreSpans\[\s*optionNode\s*\]\.textContent\s*=\s*`, score = \${score}`;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -287,7 +281,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,13 +293,13 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
--fcc-editable-region--
|
||||
--fcc-editable-region--
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
@@ -328,5 +322,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,336 @@
|
||||
---
|
||||
id: 657cd762ea9e6a47c459ee8b
|
||||
title: Step 31
|
||||
challengeType: 0
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To test out selecting a radio button option, call the `updateRadioOption` function and pass in the numbers `0` and `10` for the arguments.
|
||||
|
||||
Roll the dice again and you should see that the first radio button is enabled and displays a current score of `10`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `updateRadioOption` inside the `else` clause of the `rollDiceBtn` callback function.
|
||||
|
||||
```js
|
||||
assert.match(code, /updateRadioOption\(.*\);?/);
|
||||
```
|
||||
|
||||
You should have the arguments of `0` and `10` for the `updateRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /updateRadioOption\(\s*0\s*,\s*10\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,32 +1,20 @@
|
||||
---
|
||||
id: 64a24015fe4fbd02a16cbbe7
|
||||
title: Step 29
|
||||
id: 657cf2b586b3495a69394d7c
|
||||
title: Step 32
|
||||
challengeType: 0
|
||||
dashedName: step-29
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Using the `new Set()` constructor, create a set from `sortNumbers` and store it in a variable named `uniqueNumbers`. This will filter unique numbers from the `sortNumbers` array.
|
||||
Now that you have verified the `updateRadioOption` function works, remove the function call from your `else` clause.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable called `uniqueNumbers`.
|
||||
You should remove the `updateRadioOption` function call from your `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbers/);
|
||||
```
|
||||
|
||||
You should assign an empty array to your `uniqueNumbers` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbers\s*=\s*\[.*\]/);
|
||||
```
|
||||
|
||||
You should convert the `Set` back into an array using the following syntax: `[...new Set(sortNumbers)]`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbers\s*=\s*\[\.\.\.new\s+Set\(\s*sortNumbers\s*\)\]/);
|
||||
assert.notMatch(code, /updateRadioOption\(\s*0\s*,\s*10\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -293,7 +281,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -305,12 +293,12 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
--fcc-editable-region--
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
@@ -319,6 +307,9 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
--fcc-editable-region--
|
||||
updateRadioOption(0, 10);
|
||||
--fcc-editable-region--
|
||||
}
|
||||
});
|
||||
|
||||
@@ -333,5 +324,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,26 +1,34 @@
|
||||
---
|
||||
id: 64ae57bf4eac6002c85af0e0
|
||||
title: Step 41
|
||||
id: 657cf677438e705eab9fd1f9
|
||||
title: Step 33
|
||||
challengeType: 0
|
||||
dashedName: step-41
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You need to create a function named `resetRadioOption` which will be used to reset the radio option.
|
||||
If you roll the dice and get a `"Three of a kind"` or `"Four of a kind"`, then you can get a score totalling the sum of all five dice values. For the next few steps, you will build out an algorithm that tracks any duplicates found in the `diceValuesArr` and displays a score next to the first two radio buttons.
|
||||
|
||||
Start by creating an arrow function called `getHighestDuplicates` that has a parameter called `arr`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `resetRadioOption` function.
|
||||
You should have a function called `getHighestDuplicates`.
|
||||
|
||||
```js
|
||||
assert.isFunction(resetRadioOption);
|
||||
assert.isFunction(getHighestDuplicates);
|
||||
```
|
||||
|
||||
Your `resetRadioOption` should be an arrow function.
|
||||
Your `getHighestDuplicates` should use the arrow syntax.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetRadioOption\s*=\s*\(.*\)\s*=>\s*{[\s\S]*};?/);
|
||||
assert.match(code, /const\s+getHighestDuplicates\s*=\s*\(?.*\)?\s*=>\s*{\s*}\s*;?/);
|
||||
```
|
||||
|
||||
Your `getHighestDuplicates` function should have a parameter called `arr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+getHighestDuplicates\s*=\s*\(?\s*arr\s*\)?\s*=>\s*{\s*}\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -287,7 +295,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,38 +307,15 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
--fcc-editable-region--
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
@@ -339,7 +324,6 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -354,5 +338,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,337 @@
|
||||
---
|
||||
id: 657cfad68610a4654bb171f4
|
||||
title: Step 34
|
||||
challengeType: 0
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To detect if a roll result is a `"Three of a kind"` or a `"Four of a kind"`, you will need to count the number of occurrences for each unique number in the `arr`.
|
||||
|
||||
Inside your `getHighestDuplicates` function, create a `const` variable called `counts` and assign it an empty object.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `getHighestDuplicates` function should have a `counts` variable.
|
||||
|
||||
```js
|
||||
assert.match(getHighestDuplicates.toString(), /counts\s*=/);
|
||||
```
|
||||
|
||||
Your `counts` variable should be an empty object.
|
||||
|
||||
```js
|
||||
assert.match(getHighestDuplicates.toString(), /counts\s*=\s*\{\s*\};?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const getHighestDuplicates = (arr) => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,28 +1,20 @@
|
||||
---
|
||||
id: 64a2391ae5a6b3022bc1ce6e
|
||||
title: Step 27
|
||||
id: 657d009db786a869aa68acfa
|
||||
title: Step 35
|
||||
challengeType: 0
|
||||
dashedName: step-27
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In the game, the player has the chance to hit a small or large straight. A small straight is when four of the dice have consecutive values. A large straight is when all five dice have consecutive values.
|
||||
|
||||
To detect small and large straights, create an arrow function called `straightDetector` with a parameter of `arr`.
|
||||
Below your `counts` variable, create a `for...of` loop that will iterate through your `arr`. The variable name for the `for...of` loop should be called `num`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a function called `straightDetector`.
|
||||
You should have a `for...of` loop with a variable named `num`.
|
||||
|
||||
```js
|
||||
assert.isFunction(straightDetector)
|
||||
```
|
||||
|
||||
Your function should be an arrow function with `arr` for the parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*?const\s+straightDetector\s*=\s*\(\s*arr\s*\)\s*=>\s*{?/s);
|
||||
assert.match(code, /for\s*\(\s*(const|let|var)\s+num\s+of\s+arr\s*\)\s*{\s*}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -289,7 +281,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -301,8 +293,17 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -326,5 +327,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 64ae5180ff093301b90147cc
|
||||
id: 657d02cbb9c5416bef6a5023
|
||||
title: Step 36
|
||||
challengeType: 0
|
||||
dashedName: step-36
|
||||
@@ -7,20 +7,30 @@ dashedName: step-36
|
||||
|
||||
# --description--
|
||||
|
||||
Use an `if` statement to check if `smallStraightLogic` includes the value of `stringifyArray` and if it does, then call the function `updateRadioOption` with arguments of `3` and `30`. The `3` represents the option node and the `30` represents the score.
|
||||
For each iteration in the `arr`, you will need to check if the current number exists in the `counts` object.
|
||||
|
||||
Inside your `for...of` loop, add an `if` statement to check if the `num` key exists in the `counts` object. If so, increment the value of `counts[num]` by `1`.
|
||||
|
||||
Below your `if` statement, include an `else` clause that assigns `1` to `counts[num]` for the first occurrence of that number in the `counts` object.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `if` statement that checks if `smallStraightLogic` includes the value of `stringifyArray`.
|
||||
You should have an `if` statement with a condition of `counts[num]`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*smallStraightLogic\s*\.\s*includes\s*\(\s*stringifyArray\s*\)\s*\)\s*{/);
|
||||
assert.match(code, /if\s*\(\s*counts\[num\]\s*\)/);
|
||||
```
|
||||
|
||||
You should call the function `updateRadioOption` with arguments of `3` and `30`.
|
||||
You should use the `++` operator to increment the value of `counts[num]` by `1` inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*smallStraightLogic\s*\.\s*includes\s*\(\s*stringifyArray\s*\)\s*\)\s*{\s*updateRadioOption\s*\(\s*3\s*,\s*30\s*\)\s*;?\s*}/);
|
||||
assert.match(code, /counts\[num\]\s*\+\s*=\s*1|counts\[num\]\+\+/);
|
||||
```
|
||||
|
||||
You should assign `1` to `counts[num]` inside your `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*\{\s*counts\[num\]\s*=\s*1\s*;?\s*\}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -287,7 +297,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -305,18 +315,15 @@ const updateRadioOption = (optionNode, score) => {
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
for (const num of arr) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
@@ -339,5 +346,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,26 +1,28 @@
|
||||
---
|
||||
id: 64ae500423fa16018a83fa31
|
||||
title: Step 35
|
||||
id: 657d068a236fb16f00183e2b
|
||||
title: Step 37
|
||||
challengeType: 0
|
||||
dashedName: step-35
|
||||
dashedName: step-37
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Lastly, use the `optionNode` parameter to target the `scoreSpans` and set its `textContent` property to `, score = ${score}`.
|
||||
The next step is to keep track of when a particular number appears three or four times within the `arr`.
|
||||
|
||||
Use `let` to create a `highestCount` variable and assign it the value of `0`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should target the `scoreSpans` using the `optionNode` parameter.
|
||||
You should have a `let` variable called `highestCount`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreSpans\[\s*optionNode\s*\]/);
|
||||
assert.match(code, /let\s*highestCount\s*/);
|
||||
```
|
||||
|
||||
You should set the `textContent` property of the `scoreSpans[optionNode]` to `, score = ${score}`.
|
||||
Your `highestCount` variable should have a value of `0`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreSpans\[\s*optionNode\s*\]\.textContent\s*=\s*`, score = \${score}`/);
|
||||
assert.match(code, /let\s*highestCount\s*=\s*0\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -287,7 +289,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -302,18 +304,23 @@ const updateStats = () => {
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -337,5 +344,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,26 +1,20 @@
|
||||
---
|
||||
id: 64a7cc96491a05022098d7b0
|
||||
title: Step 33
|
||||
id: 657d0a5bf57d5c721d5e82e4
|
||||
title: Step 38
|
||||
challengeType: 0
|
||||
dashedName: step-33
|
||||
dashedName: step-38
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Use the `optionNode` parameter to target the `scoreInputs` and set its `disabled` property to `false`.
|
||||
Next, create another `for...of` loop that loops through the `arr`. The variable name for the `for...of` loop should be called `num`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should target the `scoreInputs` using the `optionNode` argument.
|
||||
You should have a `for...of` loop with a variable named `num`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\[\s*optionNode\s*\]/);
|
||||
```
|
||||
|
||||
You should set the `disabled` property of the `scoreInputs` to `false`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\[\s*optionNode\s*\]\.disabled\s*=\s*false/);
|
||||
assert.match(code, /for\s*\(\s*(const|let|var)\s+num\s+of\s+arr\s*\)\s*{\s*}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -287,7 +281,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -300,18 +294,27 @@ const updateStats = () => {
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
let highestCount = 0;
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -335,5 +338,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,20 +1,28 @@
|
||||
---
|
||||
id: 64ae54048b468302209dd977
|
||||
title: Step 38
|
||||
id: 657d0b35f0d14873018d02fa
|
||||
title: Step 39
|
||||
challengeType: 0
|
||||
dashedName: step-38
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Finally, call the `updateRadioOption` with the arguments `5` and `0`. This will work when the other 2 `if` statements are `false`.
|
||||
For each iteration of the loop, you will need to get the current duplicate count for each number in the `arr`.
|
||||
|
||||
Create a `const` variable called `count` and assign it the value of `counts[num]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the function `updateRadioOption` with arguments of `5` and `0`.
|
||||
You should have a variable called `count`.
|
||||
|
||||
```js
|
||||
assert.match(code, /updateRadioOption\s*\(\s*5\s*,\s*0\s*\)/);
|
||||
assert.match(code, /for\s*\(\s*const\s+num\s+of\s+arr\s*\)\s*{\s*const\s+count\s*=.*\s*}/);
|
||||
```
|
||||
|
||||
You should assign `counts[num]` to your `count` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /for\s*\(\s*const\s+num\s+of\s+arr\s*\)\s*{\s*const\s+count\s*=\s*counts\[num\]\s*;?\s*}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -281,7 +289,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,25 +307,24 @@ const updateRadioOption = (optionNode, score) => {
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
let highestCount = 0;
|
||||
|
||||
--fcc-editable-region--
|
||||
for (const num of arr) {
|
||||
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -341,5 +348,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 64ae561e7f4217029684cefd
|
||||
id: 657d0de92782dd7532563649
|
||||
title: Step 40
|
||||
challengeType: 0
|
||||
dashedName: step-40
|
||||
@@ -7,14 +7,20 @@ dashedName: step-40
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the event listener for the `rollDiceBtn` button, call the `findRollResult` function passing `diceValuesArr` as the argument . This will display the results of the roll on the screen every time the user clicks the roll dice button.
|
||||
To detect if the dice roll produced a `"Three of a kind"`, you will need to create an `if` statement to check if the current count is greater than or equal to `3` and greater than the current highest count. If so, assign `count` to the `highestCount` variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the function `findRollResult` with the argument of `diceValuesArr`.
|
||||
Your `if` statement should have the condition of `count >= 3 && count > highestCount`.
|
||||
|
||||
```js
|
||||
assert.match(code, /findRollResult\s*\(\s*diceValuesArr\s*\)/);
|
||||
assert.match(code, /if\s*\(\s*count\s*>=\s*3\s*&&\s*count\s*>\s*highestCount\s*\)\s*\{?\s*[\s\S]*?\}?/);
|
||||
```
|
||||
|
||||
You should assign `count` to your `highestCount` variable inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*count\s*>=\s*3\s*&&\s*count\s*>\s*highestCount\s*\)\s*\{?\s*highestCount\s*=\s*count\s*;?\s*\}?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -281,7 +287,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,27 +305,25 @@ const updateRadioOption = (optionNode, score) => {
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
let highestCount = 0;
|
||||
|
||||
--fcc-editable-region--
|
||||
for (const num of arr) {
|
||||
const count = counts[num];
|
||||
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -329,9 +333,6 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
});
|
||||
|
||||
@@ -346,5 +347,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,353 @@
|
||||
---
|
||||
id: 657d0ff4bcc54e76bd79651b
|
||||
title: Step 41
|
||||
challengeType: 0
|
||||
dashedName: step-41
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To detect if the dice roll produced a `"Four of a kind"`, you will need to create an `if` statement to check if the current count is greater than or equal to `4` and greater than the current highest count. If so, assign `count` to the `highestCount` variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `if` statement should have the condition of `count >= 4 && count > highestCount`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*count\s*>=\s*4\s*&&\s*count\s*>\s*highestCount\s*\)\s*\{?\s*[\s\S]*?\}?/);
|
||||
```
|
||||
|
||||
You should assign `count` to your `highestCount` variable inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*count\s*>=\s*4\s*&&\s*count\s*>\s*highestCount\s*\)\s*\{?\s*highestCount\s*=\s*count\s*;?\s*\}?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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;
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,385 @@
|
||||
---
|
||||
id: 657d10e12efdd577d27597ff
|
||||
title: Step 42
|
||||
challengeType: 0
|
||||
dashedName: step-42
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user rolls a `"Three of a kind"` or `"Four of a kind"`, then they will receive a score totalling the sum of all five dice values.
|
||||
|
||||
Use the `reduce` method on `diceValuesArr`. For the callback function, use `a` and `b` as parameters. Within the callback function, return the sum of `a` and `b`. For the initial value, use the number `0`.
|
||||
|
||||
Finally, assign the entire result to a `const` variable called `sumOfAllDice`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable named `sumOfAllDice`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*sumOfAllDice/);
|
||||
```
|
||||
|
||||
You should use the `reduce` method on the `diceValuesArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*diceValuesArr\s*\.\s*reduce/);
|
||||
```
|
||||
|
||||
You should have `a` and `b` for the parameters inside the callback function for the `reduce` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*diceValuesArr\s*\.\s*reduce\s*\(\s*\(\s*a\s*,\s*b\s*\)\s*=>/);
|
||||
```
|
||||
|
||||
You should return the sum of `a` and `b` within the callback function.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*diceValuesArr\s*\.\s*reduce\s*\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*(a\s*\+\s*b|{\s*return\s*a\s*\+\s*b\s*;?\s*})/);
|
||||
```
|
||||
|
||||
You should have the number `0` for the initial value of the `reduce` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*diceValuesArr\s*\.\s*reduce\s*\([\s\S]+,\s*0\s*\)\s*;?/);
|
||||
```
|
||||
|
||||
You should assign the result of the `reduce` method to the `sumOfAllDice` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*sumOfAllDice\s*=\s*diceValuesArr\s*\.\s*reduce.*/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,367 @@
|
||||
---
|
||||
id: 657d14f730b1797b03e1175b
|
||||
title: Step 43
|
||||
challengeType: 0
|
||||
dashedName: step-43
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the highest number of duplicates is `4` or more, then you will want to enable the radio button for the `"Four of a kind"` option and display the score next to it.
|
||||
|
||||
Add an `if` statement that checks if `highestCount` is greater than or equal to `4`. If so, call the `updateRadioOption` and pass in the number `1` and `sumOfAllDice` for the arguments.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement that checks if `highestCount` is greater than or equal to `4`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*highestCount\s*>=\s*4\s*\)\s*\{?\s*[\s\S]*?\}?/);
|
||||
```
|
||||
|
||||
You should call the `updateRadioOption` function inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*highestCount\s*>=\s*4\s*\)\s*\{?\s*updateRadioOption\s*\(\s*.*\s*\)/);
|
||||
```
|
||||
|
||||
You should have the number `1` and `sumOfAllDice` variable as arguments to your `updateRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /updateRadioOption\s*\(\s*1\s*,\s*sumOfAllDice\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,371 @@
|
||||
---
|
||||
id: 657d16efbc877d7d0d0aec1a
|
||||
title: Step 44
|
||||
challengeType: 0
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the highest number of duplicates is `3` or more, then you will want to enable the radio button for the `"Three of a kind"` option and display the score next to it.
|
||||
|
||||
Add an `if` statement that checks if `highestCount` is greater than or equal to `3`. If so, call the `updateRadioOption` and pass in the number `0` and `sumOfAllDice` for the arguments.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement that checks if `highestCount` is greater than or equal to `3`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*highestCount\s*>=\s*3\s*\)\s*\{?\s*[\s\S]*?\}?/);
|
||||
```
|
||||
|
||||
You should call the `updateRadioOption` function inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /updateRadioOption\s*\(\s*.*\s*\)/);
|
||||
```
|
||||
|
||||
You should have the number `0` and `sumOfAllDice` variable as arguments to your `updateRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*highestCount\s*>=\s*3\s*\)\s*\{?\s*updateRadioOption\s*\(\s*.*\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,28 +1,32 @@
|
||||
---
|
||||
id: 64ae530773cd7001ebacc6c1
|
||||
title: Step 37
|
||||
id: 657d17da1d6da97e2c0af800
|
||||
title: Step 45
|
||||
challengeType: 0
|
||||
dashedName: step-37
|
||||
dashedName: step-45
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create another `if` statement to check if `largeStraightLogic` includes the value of `stringifyArray` and if it does, then call the function `updateRadioOption` with arguments of `4` and `40`. The `4` represents the option node and the `40` represents the score.
|
||||
If the user does not get a `"Three of a kind"` or `"Four of kind"`, then they will not receive any points for that round.
|
||||
|
||||
At the end of your `getHighestDuplicates` function, call the `updateRadioOption` function with the arguments of `5` and `0`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a `if` statement that checks if `largeStraightLogic` includes the value of `stringifyArray`.
|
||||
You should call the `updateRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*largeStraightLogic\s*\.\s*includes\s*\(\s*stringifyArray\s*\)\s*\)\s*{/);
|
||||
assert.match(code, /updateRadioOption\s*\(\s*.*\s*\)/);
|
||||
```
|
||||
|
||||
You should call the function `updateRadioOption` with arguments of `4` and `40`.
|
||||
You should use the numbers `5` and `0` for the arguments to your `updateRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*largeStraightLogic\s*\.\s*includes\s*\(\s*stringifyArray\s*\)\s*\)\s*{\s*updateRadioOption\s*\(\s*4\s*,\s*40\s*\)\s*;?\s*}/);
|
||||
assert.match(code, /updateRadioOption\s*\(\s*5\s*,\s*0\s*\)/);
|
||||
```
|
||||
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
@@ -287,7 +291,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -305,16 +309,37 @@ const updateRadioOption = (optionNode, score) => {
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
@@ -343,5 +368,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,366 @@
|
||||
---
|
||||
id: 657d1af3a6a54784a82a1e6d
|
||||
title: Step 46
|
||||
challengeType: 0
|
||||
dashedName: step-46
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now it is time to see the result of your `getHighestDuplicates` function.
|
||||
|
||||
Inside the `else` clause of the `rollDiceBtn` callback function, call the `getHighestDuplicates` function and pass in `diceValuesArr` for the argument.
|
||||
|
||||
Try rolling the dice a few times to see if you can get a `"Three of a kind"`, `"Four of a kind"`, or `"None of the above"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `getHighestDuplicates` function with an argument of `diceValuesArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /getHighestDuplicates\s*\(\s*diceValuesArr\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
});
|
||||
|
||||
rulesBtn.addEventListener("click", () => {
|
||||
isModalShowing = !isModalShowing;
|
||||
|
||||
if (isModalShowing) {
|
||||
rulesBtn.textContent = "Hide Rules";
|
||||
rulesContainer.style.display = "block";
|
||||
} else {
|
||||
rulesBtn.textContent = "Show Rules";
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,372 @@
|
||||
---
|
||||
id: 657d1d52d574588677347c7f
|
||||
title: Step 47
|
||||
challengeType: 0
|
||||
dashedName: step-47
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Before each dice roll, you will need to reset the values for the score `inputs` and `spans` so a new value can be displayed.
|
||||
|
||||
Start by creating an arrow function called `resetRadioOption`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `resetRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.isFunction(resetRadioOption);
|
||||
```
|
||||
|
||||
You should use arrow syntax for your `resetRadioOption` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetRadioOption\s*=\s*\(\s*\)\s*=>\s*{\s*.*\s*}\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
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";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,26 +1,28 @@
|
||||
---
|
||||
id: 64ae5d8d2ae28b030cfd035e
|
||||
title: Step 42
|
||||
id: 657d301f80931609b9a5d110
|
||||
title: Step 48
|
||||
challengeType: 0
|
||||
dashedName: step-42
|
||||
dashedName: step-48
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you need to use the `forEach` method to the `scoreInputs` array with a callback function with an argument named `input`.
|
||||
For each of the score inputs, you will need to disable the `input` and remove its checked attribute.
|
||||
|
||||
Start by using a `forEach` on the `scoreInputs`. For the callback function, use `input` for the parameter name.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should apply the `forEach` method to the `scoreInputs` variable.
|
||||
You should use a `forEach` on the `scoreInputs`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\.forEach/);
|
||||
```
|
||||
|
||||
You should apply a callback function to the `forEach` method with an argument called `input`.
|
||||
You should apply a callback function to the `forEach` method with a parameter called `input`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreInputs\.forEach\(\s*(function\s*\(\s*input\s*\)|\(\s*input\s*\)\s*=>)/);
|
||||
assert.match(code, /scoreInputs\.forEach\(\s*\(\s*input\s*\)?\s*=>/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -287,7 +289,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,41 +301,54 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const resetRadioOption = () => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
@@ -341,7 +356,7 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -356,5 +371,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,23 +1,23 @@
|
||||
---
|
||||
id: 64ae6a43e797ab035c56d88b
|
||||
title: Step 43
|
||||
id: 657d368b5115bc137f38220d
|
||||
title: Step 49
|
||||
challengeType: 0
|
||||
dashedName: step-43
|
||||
dashedName: step-49
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Set the `disabled` property of the `input` element to `true`, and set the `checked` property of the `input` element to `false`.
|
||||
Inside your callback function, set the `input`'s `disabled` property to `true` and the `checked` property to `false`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should set the `disabled` property of the `input` element to `true`
|
||||
You should set the `disabled` property for the `input` to `true`.
|
||||
|
||||
```js
|
||||
assert.match(code, /input\.disabled\s*=\s*true/);
|
||||
```
|
||||
|
||||
You should set the `checked` property of the `input` element to `false`.
|
||||
You should set the `checked` property for the `input` to `false`.
|
||||
|
||||
```js
|
||||
assert.match(code, /input\.checked\s*=\s*false/);
|
||||
@@ -287,7 +287,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,43 +299,56 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
const getHighestDuplicates = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
for (const num of arr) {
|
||||
if (counts[num]) {
|
||||
counts[num]++;
|
||||
} else {
|
||||
counts[num] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
|
||||
});
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
@@ -343,7 +356,7 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -358,5 +371,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,13 +1,17 @@
|
||||
---
|
||||
id: 64ae6aff1af3780391f3a0a0
|
||||
title: Step 44
|
||||
id: 657d374ef92a36145abdd215
|
||||
title: Step 50
|
||||
challengeType: 0
|
||||
dashedName: step-44
|
||||
dashedName: step-50
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Apply the `forEach` method to the `scoreSpans` that you can target all the `span` elements in the `scoreInputs` element. Then apply a callback function with `span` as argument. Inside the callback function, set the `textContent` property of the `span` element to empty string.
|
||||
For each of the score `span` elements, you will need to reset the text content.
|
||||
|
||||
Start by adding a `forEach` to your `scoreSpans` variable. For the callback function, use `span` for the parameter name.
|
||||
|
||||
Inside the callback function, set text content for each `span` to an empty string.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -17,16 +21,16 @@ You should apply the `forEach` method to the `scoreSpans` variable.
|
||||
assert.match(code, /scoreSpans\.forEach/);
|
||||
```
|
||||
|
||||
You should apply a callback function to the `forEach` method with argument of `span`.
|
||||
You should apply a callback function to the `forEach` method with parameter called `span`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreSpans\.forEach\(\s*(function\s*\(\s*span\s*\)|\(\s*span\s*\)\s*=>)/);
|
||||
assert.match(code, /scoreSpans\.forEach\(\s*\(?\s*span\s*\)?\s*=>\s*{[\s\S]*}\s*\)/);
|
||||
```
|
||||
|
||||
You should set the `textContent` property of the `span` element to `""`.
|
||||
You should set the `textContent` property of the `span` element to an empty string.
|
||||
|
||||
```js
|
||||
assert.match(code, /span\.textContent\s*=\s*["']["']/);
|
||||
assert.match(code, /span\.textContent\s*=\s*["']["'];?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -293,7 +297,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -305,6 +309,48 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -315,35 +361,6 @@ const resetRadioOption = () => {
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
@@ -351,7 +368,7 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
rolls++;
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -366,5 +383,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,20 +1,22 @@
|
||||
---
|
||||
id: 64ae74510e6aed04a975f72f
|
||||
title: Step 47
|
||||
id: 657d397542d1a2162407ac39
|
||||
title: Step 51
|
||||
challengeType: 0
|
||||
dashedName: step-47
|
||||
dashedName: step-51
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `scoreInputs` is an array of radio input fields. Create a `for` loop to iterate through each element. Within the loop, create a variable named `radioButton` to represent the current element of the `scoreInputs` array.
|
||||
To see the results of your `resetRadioOption` function, you will need to call the function inside the `rollDiceBtn` callback function.
|
||||
|
||||
Now, try rolling the dice again and you should see that the previous score `inputs` and `spans` reset before each new roll.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `for` of loop to iterate through the `scoreInputs` array. Within the loop, create a variable named `radioButton` to represent the current element of the `scoreInputs` array.
|
||||
You should call the `resetRadioOption` function inside the `rollDiceBtn` callback function.
|
||||
|
||||
```js
|
||||
assert.match(code, /for\s*\(\s*(const|let|var)\s+radioButton\s+of\s+scoreInputs\s*\)\s*{\s*}/);
|
||||
assert.match(code, /resetRadioOption\(\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -281,7 +283,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -293,6 +295,48 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -304,43 +348,17 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -355,14 +373,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
keepScoreBtn.addEventListener("click", () => {
|
||||
let selectedValue;
|
||||
let achieved;
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,390 @@
|
||||
---
|
||||
id: 657d3ab710745d17697c633a
|
||||
title: Step 52
|
||||
challengeType: 0
|
||||
dashedName: step-52
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
When you roll the dice and make a selection, you are not able to keep the score you selected and move onto the next round. In the next few steps, you will build out an algorithm that keeps track of and displays each score for all six rounds of the game.
|
||||
|
||||
Start by creating an arrow function called `updateScore` that has two parameters called `selectedValue` and `achieved`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `updateScore` function.
|
||||
|
||||
```js
|
||||
assert.isFunction(updateScore);
|
||||
```
|
||||
|
||||
Your `updateScore` function should use arrow syntax.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+updateScore\s*=\s*\(\s*.*\s*\)\s*=>\s*{/);
|
||||
```
|
||||
|
||||
Your `updateScore` function should have two parameters named `selectedValue` and `achieved`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+updateScore\s*=\s*\(\s*selectedValue\s*,\s*achieved\s*\)\s*=>\s*{/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,34 +1,28 @@
|
||||
---
|
||||
id: 64ae70794c6760043f553998
|
||||
title: Step 45
|
||||
id: 657d459868330c1e1da6bd49
|
||||
title: Step 53
|
||||
challengeType: 0
|
||||
dashedName: step-45
|
||||
dashedName: step-53
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next is to setup the functionality for the `keepScoreBtn`.
|
||||
The `selectedValue` parameter represents the option the user chose during that round.
|
||||
|
||||
Start by adding an `addEventListener()` to your `keepScoreBtn`. For the first argument, pass in a `click` event and for the second argument pass in an empty callback function.
|
||||
To update the score, you will need to use the `+=` compound assignment operator to add the `selectedValue` to the `totalScore`. Make sure to wrap your `selectedValue` parameter inside a `parseInt` since this string value needs to be converted to an integer.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should add an `addEventListener()` to your `keepScoreBtn` variable.
|
||||
You should convert the `selectedValue` into an integer using the `parseInt()` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /keepScoreBtn\.addEventListener\(\s*["']click["']/);
|
||||
assert.match(code, /.*\s*parseInt\s*\(\s*selectedValue\s*\)\s*;?/);
|
||||
```
|
||||
|
||||
Your `addEventListener()` should have a `click` event for the first argument.
|
||||
You should use the `+=` operator to add `parseInt(selectedValue)` to the `totalScore` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /keepScoreBtn\.addEventListener\(\s*["']click["']/);
|
||||
```
|
||||
|
||||
Your `addEventListener()` should have a callback function for the second argument.
|
||||
|
||||
```js
|
||||
assert.match(code, /keepScoreBtn\.addEventListener\(\s*["']click["']\s*,\s*(function|[^{]*=>\s*{)/);
|
||||
assert.match(code, /totalScore\s*\+=\s*parseInt\s*\(\s*selectedValue\s*\)\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -295,7 +289,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -307,6 +301,54 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -318,43 +360,15 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -369,9 +383,4 @@ rulesBtn.addEventListener("click", () => {
|
||||
rulesContainer.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -0,0 +1,387 @@
|
||||
---
|
||||
id: 657d491c439d642176fc2fc8
|
||||
title: Step 54
|
||||
challengeType: 0
|
||||
dashedName: step-54
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, set the text content of `totalScoreText` to the value of `totalScore`.
|
||||
|
||||
Below that, append the following template literal to the `scoreHistory` element's HTML: `<li>${achieved} : ${selectedValue}</li>`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign `totalScore` to the `textContent` property of `totalScoreText`.
|
||||
|
||||
```js
|
||||
assert.match(code, /totalScoreText\s*\.\s*textContent\s*=\s*totalScore\s*;?/);
|
||||
```
|
||||
|
||||
You should use the `+=` operator to append `<li>${achieved} : ${selectedValue}</li>` to the `innerHTML` property of `scoreHistory`.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreHistory\s*\.\s*innerHTML\s*\+\s*\=\s*`<li>\s*\$\{\s*achieved\s*\}\s*:\s*\$\{\s*selectedValue\s*\}\s*<\/li>`\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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";
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,397 @@
|
||||
---
|
||||
id: 657d4a7e2002f822c646204b
|
||||
title: Step 55
|
||||
challengeType: 0
|
||||
dashedName: step-55
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
After a user makes a selection, they should be able to keep that score and move onto the next round.
|
||||
|
||||
Add an event listener to your `keepScoreBtn` variable that takes in a `click` event for the first argument and an empty arrow function for the second argument.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an event listener on your `keepScoreBtn` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /keepScoreBtn\.addEventListener\(\s*.*\s*/);
|
||||
```
|
||||
|
||||
Your event listener should have a `click` event for the first argument.
|
||||
|
||||
```js
|
||||
assert.match(code, /keepScoreBtn\.addEventListener\(\s*["']click["']/);
|
||||
```
|
||||
|
||||
Your event listener should have an empty arrow function for the second argument.
|
||||
|
||||
```js
|
||||
assert.match(code, /keepScoreBtn\.addEventListener\(\s*["']click["']\s*,\s*[^{]*=>\s*{/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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";
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,13 +1,15 @@
|
||||
---
|
||||
id: 64ae722962105404772b7618
|
||||
title: Step 46
|
||||
id: 657d4c910e9a5724886b9f92
|
||||
title: Step 56
|
||||
challengeType: 0
|
||||
dashedName: step-46
|
||||
dashedName: step-56
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, declare two unassigned `let` variables named `selectedValue` and `achieved`. These will be used to store the selected value and the achieved value respectively.
|
||||
When a radio button is checked, you will need to save its `value` and `id`.
|
||||
|
||||
Inside your event listener function, create two `let` variables called `selectedValue`, and `achieved`.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -287,7 +289,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -299,6 +301,55 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -310,43 +361,15 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -362,10 +385,9 @@ rulesBtn.addEventListener("click", () => {
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
keepScoreBtn.addEventListener("click", () => {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,20 +1,22 @@
|
||||
---
|
||||
id: 64b8c2130652b4013da1cc8a
|
||||
title: Step 51
|
||||
id: 657d4d734e523a257125596b
|
||||
title: Step 57
|
||||
challengeType: 0
|
||||
dashedName: step-51
|
||||
dashedName: step-57
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create an `else` statement and display `Please select an option or roll the dice` using `alert()`.
|
||||
To figure out which selection was made, you will need to loop through each radio button to see which one has the checked attribute.
|
||||
|
||||
Use a `for...of` loop to loop through each of the `scoreInputs`. The variable name for the `for...of` loop should be called `radioButton`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `else` statement and display `Please select an option or roll the dice` using `alert()`.
|
||||
You should have a `for...of` loop with a variable named `radioButton`.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*alert\s*\(\s*['"`]Please\s*select\s*an\s*option\s*or\s*roll\s*the\s*dice['"`]\s*\)\s*;?\s*}/);
|
||||
assert.match(code, /for\s*\(\s*(const|let|var)\s+radioButton\s+of\s+scoreInputs\s*\)\s*{\s*}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -281,7 +283,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -293,6 +295,55 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -304,43 +355,15 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -356,35 +379,11 @@ rulesBtn.addEventListener("click", () => {
|
||||
}
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,37 +1,41 @@
|
||||
---
|
||||
id: 64b457bb4cd0e2013d839c92
|
||||
title: Step 48
|
||||
id: 657d4eb2785e0d268dbd2ad2
|
||||
title: Step 58
|
||||
challengeType: 0
|
||||
dashedName: step-48
|
||||
dashedName: step-58
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the loop, use an `if` statement to check if the current element `radioButton` is checked using `.checked` property. If it is `true`, then reassign the `selectedValue` to `radioButton.value`.
|
||||
If the current radio button inside the loop has the checked attribute, then you will need to get its `value` and `id`.
|
||||
|
||||
Then, inside the `if` statement, reassign the `achieved` variable to `radioButton.id`. In the end, add a `break` statement to exit the loop.
|
||||
Add an `if` statement inside your `for...loop`, with a condition of `radioButton.checked`.
|
||||
|
||||
Inside your `if` statement, assign `radioButton.value` to `selectedValue` and assign `radioButton.id` to `achieved`.
|
||||
|
||||
At the bottom of your `if` statement, add the `break` keyword to ensure that you break out of the loop when the selected radio button was found.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `if` statement to check if the current element `radioButton` is checked using `.checked` property.
|
||||
You should have an `if` statement to check if the current `radioButton` has the `checked` property.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*radioButton\s*\.\s*checked\s*\)\s*{\s*[^}]*\s*}/);
|
||||
```
|
||||
|
||||
you should reassign the `selectedValue` to `radioButton.value`.
|
||||
You should assign `radioButton.value` to `selectedValue`.
|
||||
|
||||
```js
|
||||
assert.match(code, /selectedValue\s*=\s*radioButton\s*\.\s*value/);
|
||||
```
|
||||
|
||||
you should reassign the `achieved` variable to `radioButton.id`.
|
||||
You should assign `radioButton.id` to `achieved`.
|
||||
|
||||
```js
|
||||
assert.match(code, /achieved\s*=\s*radioButton\s*\.\s*id/);
|
||||
```
|
||||
|
||||
You should add a `break` statement to exit the loop.
|
||||
You should have a `break` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /break\s*;?/);
|
||||
@@ -301,7 +305,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -313,6 +317,55 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -324,43 +377,15 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -380,11 +405,10 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
let selectedValue;
|
||||
let achieved;
|
||||
|
||||
--fcc-editable-region--
|
||||
for (const radioButton of scoreInputs) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
```
|
||||
@@ -1,35 +1,47 @@
|
||||
---
|
||||
id: 64b45a195557d801660f07d5
|
||||
title: Step 49
|
||||
id: 657d509785c2f12828d7196f
|
||||
title: Step 59
|
||||
challengeType: 0
|
||||
dashedName: step-49
|
||||
dashedName: step-59
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You should write an `if` statement to check against the `selectedValue` variable. Inside the `if` statement reassign `rolls` to `0`, increment `round` by `1`.Then, you will call the functions named `updateStats` and `resetRadioOption`. Finally, you will call the function named `updateScore` and pass in arguments `selectedValue` and `achieved`.
|
||||
If the user makes a selection, then the rounds, rolls and scores should be updated.
|
||||
|
||||
Add an `if` statement, to check if `selectedValue` is truthy. If so, reassign the number `0` to `rolls` and increment `round` by `1`.
|
||||
|
||||
Then, call the `updateStats` and `resetRadioOption` functions. And lastly, call the `updateScore` function and pass in `selectedValue` and `achieved` for the arguments.
|
||||
|
||||
Now you should be able to roll the dice, make a selection keep a score and have the score display under the score history.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `if` statement to check against the `selectedValue` variable.
|
||||
You should have an `if` statement to check the `selectedValue` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*selectedValue\s*\)\s*{\s*[^}]*\s*}/);
|
||||
```
|
||||
|
||||
Inside the `if` statement, you will reassign `rolls` to `0`, increment `round` by `1`.
|
||||
You should reassign `rolls` to `0` inside your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*if\s*\(\s*selectedValue\s*\)\s*{\s*rolls\s*=\s*0\s*;?.*}/s);
|
||||
```
|
||||
|
||||
You should increment `round` by `1`.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*if\s*\(\s*selectedValue\s*\)\s*{\s*rolls\s*=\s*0\s*;?\s*round\s*\+\+\s*;?.*}/s);
|
||||
```
|
||||
|
||||
You will call the functions named `updateStats` and `resetRadioOption`.
|
||||
You should call the `updateStats` and `resetRadioOption` functions.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*selectedValue\s*\)\s*{\s*rolls\s*=\s*0\s*;?\s*round\s*\+\+\s*;?\s*updateStats\s*\(\s*\)\s*;?\s*resetRadioOption\s*\(\s*\).*}/s);
|
||||
```
|
||||
|
||||
You will call the function named `updateScore` and pass in arguments `selectedValue` and `achieved`.
|
||||
You should call the `updateScore` function and pass in `selectedValue` and `achieved` for arguments.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*selectedValue\s*\)\s*{\s*rolls\s*=\s*0\s*;?\s*round\s*\+\+\s*;?\s*updateStats\s*\(\s*\)\s*;?\s*resetRadioOption\s*\(\s*\)\s*;?\s*updateScore\s*\(\s*selectedValue\s*,\s*achieved\s*\)\s*;?\s*}/);
|
||||
@@ -299,7 +311,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -311,6 +323,55 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -322,43 +383,15 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -390,5 +423,4 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,417 @@
|
||||
---
|
||||
id: 657d535901979b2a4b2a345c
|
||||
title: Step 60
|
||||
challengeType: 0
|
||||
dashedName: step-60
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If you try to click on the keep score button without making a selection, then nothing happens.
|
||||
|
||||
To fix this, add an `else` clause to your `if` statement, and place an `alert` inside. For your `alert`, use the following message: `"Please select an option or roll the dice"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `else` clause below your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /.*else\s*{\s*[\s\S]*\s*}/);
|
||||
```
|
||||
|
||||
You should have an `alert` inside your `else` clause.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*alert\s*\(\s*.*\s*\)\s*;?\s*}/);
|
||||
```
|
||||
|
||||
Your `alert` should display the following message: `Please select an option or roll the dice`.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*{\s*alert\s*\(\s*['"`]Please\s*select\s*an\s*option\s*or\s*roll\s*the\s*dice['"`]\s*\)\s*;?\s*}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
});
|
||||
```
|
||||
@@ -1,40 +1,32 @@
|
||||
---
|
||||
id: 64b45d46f718ff01988c51ad
|
||||
title: Step 50
|
||||
id: 657d552526c0d72beb57160f
|
||||
title: Step 61
|
||||
challengeType: 0
|
||||
dashedName: step-50
|
||||
dashedName: step-61
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create an `if` statement to check if the value of `round` is greater than `6`. Then, create a setTimeout function to show the alert message after 500 milliseconds. The alert message should be `Game over! Your total score is ${totalScore}`. After the alert message, call the `resetGame` function to reset the game.
|
||||
At this point in the game, you are able to roll the dice, make a selection and play for a few rounds. However, you should notice that there is no end to the game and there are infinite rounds.
|
||||
|
||||
According to the rules, there should be a total of six rounds and then the game ends with the final score.
|
||||
|
||||
Inside the `if` statement for your `keepScoreBtn` event listener, add a new `if` statement to check if `round` is greater than the number `6`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `if` statement to check if `round` is more than `6` or not.
|
||||
|
||||
You should nest a new `if` statement inside your existing `if` statement that checks if `selectedValue` is truthy.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*selectedValue\s*\)\s*{[\s\S]+if\s*\(/);
|
||||
```
|
||||
|
||||
You should check if `round` is greater than the number `6` in your new `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*round\s*>\s*6\s*\)\s*{\s*[^}]*\s*}/);
|
||||
```
|
||||
|
||||
You should create a `setTimeout` function to show the alert message after 500 milliseconds.
|
||||
|
||||
```js
|
||||
assert.match(code, /setTimeout\s*\(\s*\(\)\s*=>\s*{\s*[\s\S]*?\s*}\s*,\s*500\s*\)/);
|
||||
```
|
||||
|
||||
You should use `alert` to show the alert message stating `Game over! Your total score is ${totalScore}` inside the setTimeout function.
|
||||
|
||||
```js
|
||||
assert.match(code, /setTimeout\s*\(\s*\(\s*\)\s*=>\s*{\s*[^}]*\balert\s*\(\s*`Game\s*Over!\s*Your\s*total\s*score\s*is\s*\${totalScore}`\s*\)[^}]*\s*}\s*,\s*500\s*\)/);
|
||||
```
|
||||
|
||||
You should call the `resetGame` function after the alert message.
|
||||
|
||||
```js
|
||||
assert.match(code, /setTimeout\s*\(\s*\(\s*\)\s*=>\s*{\s*alert\s*\(\s*`Game\s*Over!\s*Your\s*total\s*score\s*is\s*\${totalScore}`\s*\)\s*;\s*resetGame\s*\(\s*\);\s*},\s*500\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
@@ -299,7 +291,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -311,6 +303,55 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -322,43 +363,15 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -393,9 +406,10 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,416 @@
|
||||
---
|
||||
id: 657dfc42adf7696260da54f1
|
||||
title: Step 62
|
||||
challengeType: 0
|
||||
dashedName: step-62
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `if` statement, add a `setTimeout` function that takes in a callback function and a delay set to `500` milliseconds.
|
||||
|
||||
Inside your `setTimeout` function, add an `alert` with the message of `Game Over! Your total score is ${totalScore}`.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
You should have a `setTimeout` function inside your `if` statement with a callback function and delay set to `500` milliseconds.
|
||||
|
||||
```js
|
||||
assert.match(code, /setTimeout\s*\(.*\s*=>[\s\S]*,\s*500\s*\)/);
|
||||
```
|
||||
|
||||
You should have an `alert` to show the message `Game Over! Your total score is ${totalScore}`.
|
||||
|
||||
```js
|
||||
assert.match(code, /setTimeout\s*\(\s*\(\s*\)\s*=>\s*{?\s*alert\s*\(\s*`Game\s*Over!\s*Your\s*total\s*score\s*is\s*\${totalScore}`\s*\)\s*;?\s*}?\s*,\s*500\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
--fcc-editable-region--
|
||||
if (round > 6) {
|
||||
|
||||
}
|
||||
--fcc-editable-region--
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,419 @@
|
||||
---
|
||||
id: 657dfeef78fe0364bd241d7f
|
||||
title: Step 63
|
||||
challengeType: 0
|
||||
dashedName: step-63
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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.
|
||||
|
||||
Start by creating an arrow function called `resetGame`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a function called `resetGame`.
|
||||
|
||||
```js
|
||||
assert.isFunction(resetGame);
|
||||
```
|
||||
|
||||
You should use arrow syntax for your `resetGame` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*}\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,441 @@
|
||||
---
|
||||
id: 657e01b37d256166f84be8d5
|
||||
title: Step 64
|
||||
challengeType: 0
|
||||
dashedName: step-64
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `resetGame` function, reassign the `diceValuesArr` variable to an array of five zeros.
|
||||
|
||||
Below that, reassign the variables `score`, `totalScore` and `rolls` to `0`.
|
||||
|
||||
Lastly, reassign the `round` variable to `1`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should reassign the `diceValuesArr` variable to an array of five zeros.
|
||||
|
||||
```js
|
||||
assert.match(code, /diceValuesArr\s*=\s*\[\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\]/);
|
||||
```
|
||||
|
||||
You should reassign the `score` variable to `0`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?\bscore\s*=\s*0\b.*?\s*}/s);
|
||||
```
|
||||
|
||||
You should reassign the `totalScore` variable to `0`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?\btotalScore\s*=\s*0\b.*?\s*}/s);
|
||||
```
|
||||
|
||||
You should reassign the `rolls` variable to `0`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?rolls\s*=\s*0\b.*?\s*}/s);
|
||||
```
|
||||
|
||||
You should reassign the `round` variable to `1`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?round\s*=\s*1\b.*?\s*}/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const resetGame = () => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,424 @@
|
||||
---
|
||||
id: 657e033dcf624668a1a6180b
|
||||
title: Step 65
|
||||
challengeType: 0
|
||||
dashedName: step-65
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To reset each of the dice values to show `0`, apply a `forEach` method to the `listOfAllDice` variable. For your callback function, use `dice` and `index` as parameters.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `forEach` method of the `listOfAllDice` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?listOfAllDice\.forEach\s*\(.*\)/s);
|
||||
```
|
||||
|
||||
For your callback function, you should use `dice` and `index` as parameters.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?listOfAllDice\.forEach\s*\(\s*\(\s*dice\s*,\s*index\s*\)\s*=>\s*{\s*}\s*\)/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,426 @@
|
||||
---
|
||||
id: 657e0485c9c0e469d6bc3ed1
|
||||
title: Step 66
|
||||
challengeType: 0
|
||||
dashedName: step-66
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your callback function, update the `dice` text content by assigning it the value of `diceValuesArr[index]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should access the `textContent` property of the `dice` parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?dice\s*\.\s*textContent\s*/s);
|
||||
```
|
||||
|
||||
You should assign `diceValuesArr[index]` to `dice.textContent`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+resetGame\s*=\s*\(\)\s*=>\s*{\s*.*?dice\s*\.\s*textContent\s*=\s*diceValuesArr\s*\[\s*index\s*\]/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
--fcc-editable-region--
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
|
||||
});
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,447 @@
|
||||
---
|
||||
id: 657e066025aa6c6b77f33a9b
|
||||
title: Step 67
|
||||
challengeType: 0
|
||||
dashedName: step-67
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, update the score history, total, rounds and rolls text.
|
||||
|
||||
Start by updating the text content for the `totalScoreText` by assigning it the value of `totalScore`. Below that, update the HTML content for the `scoreHistory` by assigning it an empty string.
|
||||
|
||||
Below that, update the text content for the `currentRoundRollsText` by assigning it the `rolls` variable.
|
||||
|
||||
Lastly, update the `currentRoundText` text content by assigning it the `round` variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign `totalScore` to `totalScoreText.textContent`.
|
||||
|
||||
```js
|
||||
assert.match(code, /totalScoreText\s*\.\s*textContent\s*=\s*totalScore\s*;?/);
|
||||
```
|
||||
|
||||
You should use the `innerHTML` property to set the `scoreHistory` to an empty string.
|
||||
|
||||
```js
|
||||
assert.match(code, /scoreHistory\s*\.\s*innerHTML\s*=\s*['"`]\s*['"`]\s*;?/);
|
||||
```
|
||||
|
||||
You should assign `rolls` to `currentRoundRollsText.textContent`.
|
||||
|
||||
```js
|
||||
assert.match(code, /currentRoundRollsText\s*\.\s*textContent\s*=\s*rolls\s*;?/);
|
||||
```
|
||||
|
||||
You should assign `round` to `currentRoundText.textContent`.
|
||||
|
||||
```js
|
||||
assert.match(code, /currentRoundText\s*\.\s*textContent\s*=\s*round\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,429 @@
|
||||
---
|
||||
id: 657e0846af6cff6cf9b792db
|
||||
title: Step 68
|
||||
challengeType: 0
|
||||
dashedName: step-68
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The last part of your `resetGame` function is to call the `resetRadioOption` function. This will reset all of the radio buttons.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `resetRadioOption` function inside your `resetGame` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /resetRadioOption\s*\(\s*\)\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,432 @@
|
||||
---
|
||||
id: 657e09d4802a136e868a7f5e
|
||||
title: Step 69
|
||||
challengeType: 0
|
||||
dashedName: step-69
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To reset the game after six rounds, you will need to call your `resetGame` function inside the `keepScoreBtn` event listener.
|
||||
|
||||
Now you should be able to play the game for six rounds, end the game and have it reset for you.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call your `resetGame` function inside the `keepScoreBtn` event listener.
|
||||
|
||||
```js
|
||||
assert.match(code, /resetGame\s*\(\s*\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,456 @@
|
||||
---
|
||||
id: 657e0c2c6a9d37705146f34d
|
||||
title: Step 70
|
||||
challengeType: 0
|
||||
dashedName: step-70
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user rolls a `"Three of a kind"` and a pair, then they can receive `25` points for that round. This is known as a full house.
|
||||
|
||||
For the next few steps you will build out an algorithm to check for both a `"Three of a kind"` and a pair and display that option on the screen.
|
||||
|
||||
Start by creating an arrow function called `detectFullHouse` with `arr` for the parameter name.
|
||||
|
||||
Inside the `detectFullHouse` function, create a `const` variable called `counts` and assign it an empty object.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `detectFullHouse` function.
|
||||
|
||||
```js
|
||||
assert.isFunction(detectFullHouse);
|
||||
```
|
||||
|
||||
You should use arrow syntax for your `detectFullHouse` function.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*detectFullHouse\s*=\s*\(?\s*.*\s*\)?\s*=>\s*{/);
|
||||
```
|
||||
|
||||
Your `detectFullHouse` function should have a parameter called `arr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*detectFullHouse\s*=\s*\(?\s*arr\s*\)?\s*=>\s*{/);
|
||||
```
|
||||
|
||||
You should have a `const` variable called `counts` and assign an empty object to it.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+detectFullHouse\s*=\s*\(?\s*arr\s*\)?\s*=>\s*{\s*const\s+counts\s*=\s*{\s*}\s*;?\s*}/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,436 @@
|
||||
---
|
||||
id: 657e0f2a6cb19c72b8760be5
|
||||
title: Step 71
|
||||
challengeType: 0
|
||||
dashedName: step-71
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To count the occurrences for each number, use a `for...of` loop to iterate through every element of the `arr`. The variable name for the `for...of` loop should be called `num`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use a `for...of` loop to iterate through the `arr` array.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+detectFullHouse\s*=\s*\(arr\s*\)\s*=>\s*{.*\s*for\s*\(\s*const\s+num\s+of\s+arr\s*\)\s*{\s*.*}/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,440 @@
|
||||
---
|
||||
id: 657e13351e0232761a908609
|
||||
title: Step 72
|
||||
challengeType: 0
|
||||
dashedName: step-72
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `for...of` loop, use a `ternary` operator to check if `counts[num]` is truthy. If so, then increment the count by one, otherwise initialize `counts[num]` with a value of 1.
|
||||
|
||||
Assign the entire result of your `ternary` to `counts[num]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign `counts[num] ? counts[num] + 1 : 1` to `counts[num]` in the `for...of` loop.
|
||||
|
||||
```js
|
||||
assert.match(code, /counts\[num\]\s*=\s*counts\[num\]\s*\?\s*counts\[num\]\s*\+\s*1\s*:\s*1\s*;?/s);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
--fcc-editable-region--
|
||||
for (const num of arr) {
|
||||
|
||||
}
|
||||
--fcc-editable-region--
|
||||
}
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,458 @@
|
||||
---
|
||||
id: 657e14fb165435777a597aea
|
||||
title: Step 73
|
||||
challengeType: 0
|
||||
dashedName: step-73
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the `counts` object has a value of the number `3`, then that means the user rolled a `Three of a kind`.
|
||||
|
||||
Start by using the `Object.values()` method and pass in `counts` for the argument. This will create an array of only the `counts` values.
|
||||
|
||||
Then chain the `includes` method and pass in the number `3`. This will check if `3` is inside this new array.
|
||||
|
||||
Lastly, assign that result to a `const` variable called `hasThreeOfAKind`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable called `hasThreeOfAKind`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+hasThreeOfAKind\s*=/);
|
||||
```
|
||||
|
||||
You should assign `Object.values(counts)` to your `hasThreeOfAKind` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+hasThreeOfAKind\s*=\s*Object\.values\(counts\).*/);
|
||||
```
|
||||
|
||||
You should chain `.includes(3)` to your `Object.values(counts)`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+hasThreeOfAKind\s*=\s*Object\.values\(counts\)\.includes\(3\)\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,460 @@
|
||||
---
|
||||
id: 657e180ad0a77c79d8b4b82e
|
||||
title: Step 74
|
||||
challengeType: 0
|
||||
dashedName: step-74
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the `counts` object has a value of the number `2`, then that means the user has rolled a pair.
|
||||
|
||||
Start by using the `Object.values()` method and pass in `counts` for the argument.
|
||||
|
||||
Then chain the `includes` method and pass in the number `2`. This will check if `2` is inside this new array.
|
||||
|
||||
Lastly, assign that result to a `const` variable called `hasPair`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable called `hasPair`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+hasPair\s*=/);
|
||||
```
|
||||
|
||||
You should assign `Object.values(counts)` to your `hasPair` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+hasPair\s*=\s*Object\.values\(counts\).*/);
|
||||
```
|
||||
|
||||
You should chain `.includes(2)` to your `Object.values(counts)`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+hasPair\s*=\s*Object\.values\(counts\)\.includes\(2\)\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,451 @@
|
||||
---
|
||||
id: 657e18b58d9f6a7ac1544999
|
||||
title: Step 75
|
||||
challengeType: 0
|
||||
dashedName: step-75
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user has rolled both a pair and `Three of a kind`, then they have received a `Full house` resulting in `25` points.
|
||||
|
||||
Add an `if` statement to check if both `hasThreeOfAKind` and `hasPair` are `true`. If so, call the `updateRadioOption` and pass in the numbers `2` and `25`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `if` statement should have the following condition: `hasThreeOfAKind && hasPair`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*hasThreeOfAKind\s*&&\s*hasPair\s*\)\s*{?\s*[\s\S]*?}?/);
|
||||
```
|
||||
|
||||
You should call your `updateRadioOption` function and pass `2` and `25` for the arguments.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*hasThreeOfAKind\s*&&\s*hasPair\s*\)\s*{?\s*updateRadioOption\s*\(\s*2\s*,\s*25\s*\)\s*;?\s*}?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,448 @@
|
||||
---
|
||||
id: 657e1bfa4f1f5d7d5c14d43d
|
||||
title: Step 76
|
||||
challengeType: 0
|
||||
dashedName: step-76
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user did not get a `Full house` then the option for `None of the above` should be enabled with `0` points awarded.
|
||||
|
||||
Below your `if` statement, call the `updateRadioOption` function and pass in the numbers `5` and `0` for the arguments.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `updateRadioOption` function and pass in the numbers `5` and `0` for the arguments below your `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*hasThreeOfAKind\s*&&\s*hasPair\s*\)\s*{\s*updateRadioOption\s*\(\s*2\s*,\s*25\s*\)\s*;?\s*}\s*updateRadioOption\s*\(\s*5\s*,\s*0\s*\)\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
--fcc-editable-region--
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,450 @@
|
||||
---
|
||||
id: 657e21575e71e2822f3b0abd
|
||||
title: Step 77
|
||||
challengeType: 0
|
||||
dashedName: step-77
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To see the results of your `detectFullHouse` function, call your `detectFullHouse` function inside the `rollDiceBtn` event listener and pass in the `diceValuesArr` variable for the argument.
|
||||
|
||||
Try playing a few rounds of the game to see if you can land on a `Full house`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `detectFullHouse` and pass in the `diceValuesArr` variable for the argument.
|
||||
|
||||
```js
|
||||
assert.match(code, /detectFullHouse\s*\(\s*diceValuesArr\s*\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
});
|
||||
|
||||
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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,466 @@
|
||||
---
|
||||
id: 657e230500602983e01fff6e
|
||||
title: Step 78
|
||||
challengeType: 0
|
||||
dashedName: step-78
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
For the last portion of the game, you will need to create an algorithm that checks for the presence of a straight.
|
||||
|
||||
A small straight is when four of the dice have consecutive values(`Ex. 1234`) resulting in a score of `30` points. A large straight is when all five dice have consecutive values(`Ex. 12345`) resulting in a score of `40` points.
|
||||
|
||||
Start by creating an arrow function called `checkForStraights` that has `arr` for the parameter name.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `checkForStraights` variable should be a function.
|
||||
|
||||
```js
|
||||
assert.isFunction(checkForStraights);
|
||||
```
|
||||
|
||||
Your `checkForStraights` function should use arrow syntax.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+checkForStraights\s*=\s*\(?\s*(?:arr)?\s*\)?\s*=>/);
|
||||
```
|
||||
|
||||
Your `checkForStraights` function should have a `arr` parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+checkForStraights\s*=\s*\(?\s*arr\s*\)?\s*=>/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,474 @@
|
||||
---
|
||||
id: 657e253cf2c01685ed84c1ee
|
||||
title: Step 79
|
||||
challengeType: 0
|
||||
dashedName: step-79
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To check for a small or large straight, you will need to first sort the list of numbers in the array.
|
||||
|
||||
Use the `sort` method on the `arr` parameter and pass in a callback function. For the callback function, use `a` and `b` for the parameters and implicitly return `a - b`.
|
||||
|
||||
Assign that entire result to a `const` variable called `sortedNumbersArr`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable called `sortedNumbersArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortedNumbersArr\s*=/);
|
||||
```
|
||||
|
||||
You should assign your `arr` parameter to your `sortedNumbersArr` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortedNumbersArr\s*=\s*arr.*/);
|
||||
```
|
||||
|
||||
You should apply the `sort` array method on the `arr` parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortedNumbersArr\s*=\s*arr\.sort\(.*\);?/);
|
||||
```
|
||||
|
||||
Your callback function should use `a` and `b` for the parameters and implicitly return `a - b`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+sortedNumbersArr\s*=\s*(?:arr\.sort\(\s*\(a,\s*b\)\s*=>\s*a\s*-\s*b\s*\));?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const checkForStraights = (arr) => {
|
||||
|
||||
};
|
||||
--fcc-editable-region--
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,462 @@
|
||||
---
|
||||
id: 657e27774cb16b8810c18ba8
|
||||
title: Step 80
|
||||
challengeType: 0
|
||||
dashedName: step-80
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To check for only unique numbers, you will need to use a `Set` on your `sortedNumbersArr`. Convert that result into an array using the spread operator.
|
||||
|
||||
Lastly, assign that entire result to a `const` variable called `uniqueNumbersArr`.
|
||||
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable called `uniqueNumbersArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbersArr\s*=/);
|
||||
```
|
||||
|
||||
You should spread the values of the `Set` into a new array `[...new Set(sortedNumbersArr)]`
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbersArr\s*=\s*\[\s*\.\.\.new\s+Set\(\s*sortedNumbersArr\s*\)\s*\]\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,461 @@
|
||||
---
|
||||
id: 657e2bac662a3c8f5801d550
|
||||
title: Step 81
|
||||
challengeType: 0
|
||||
dashedName: step-81
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, use the `join` method on the `uniqueNumbersArr` and assign that result to a `const` variable called `uniqueNumbersStr`. For the `join` method use an empty string for the separator.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable named `uniqueNumbersStr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbersStr\s*=?\s*;?/);
|
||||
```
|
||||
|
||||
You should the use the `join("")` method on the `uniqueNumbersArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+uniqueNumbersStr\s*=?\s*uniqueNumbersArr\.join\(\s*['"]['"]\s*\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,464 @@
|
||||
---
|
||||
id: 657e2d01d1a086908d3c9d32
|
||||
title: Step 82
|
||||
challengeType: 0
|
||||
dashedName: step-82
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
There are a total of 3 possibilities for a small straight: `"1234"`, `"2345"`, and `"3456"`.
|
||||
|
||||
Create a `const` variable called `smallStraightsArr` and assign it the value of an array containing the three string values listed above.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable named `smallStraightsArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+smallStraightsArr\s*=?\s*;?/);
|
||||
```
|
||||
|
||||
You should store the strings `1234`, `2345` and `3456` in an array and assign it to your `smallStraightsArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+smallStraightsArr\s*=?\s*\[\s*['"]1234['"]\s*,\s*['"]2345['"]\s*,\s*['"]3456['"]\s*\];?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,466 @@
|
||||
---
|
||||
id: 657e2e1f5fb69291b1294388
|
||||
title: Step 83
|
||||
challengeType: 0
|
||||
dashedName: step-83
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
There are only two possibilities for a large straight: `"12345"` and `"23456"`.
|
||||
|
||||
Create a `const` variable called `largeStraightsArr` and assign it the value of an array containing the two string values listed above.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `const` variable named `largeStraightsArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+largeStraightsArr\s*=?\s*;?/);
|
||||
```
|
||||
|
||||
You should store the strings `12345` and `23456` in an array and assign it to your `largeStraightsArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+largeStraightsArr\s*=?\s*\[\s*['"]12345['"]\s*,\s*['"]23456['"]\s*\];?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
const smallStraightsArr = ["1234", "2345", "3456"];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,467 @@
|
||||
---
|
||||
id: 657e2ecee9f60092c89338d9
|
||||
title: Step 84
|
||||
challengeType: 0
|
||||
dashedName: step-84
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user rolls a small straight, then the `Small straight` radio button option should be enabled with a score of `30` points.
|
||||
|
||||
Start by creating an `if` statement to check if `uniqueNumbersStr` is included in the `smallStraightsArr`. If so, call the `updateRadioOption` with `3` and `30` for the arguments.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `includes` method to check if `uniqueNumbersStr` is included in the `smallStraightsArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*smallStraightsArr\.includes\(uniqueNumbersStr\)\s*\)\s*{?/);
|
||||
```
|
||||
|
||||
You should call your `updateRadioOption` with `3` and `30` for the arguments.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*smallStraightsArr\.includes\(uniqueNumbersStr\)\s*\)\s*{?\s*updateRadioOption\s*\(\s*3\s*,\s*30\s*\)\s*;?\s*}?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
const smallStraightsArr = ["1234", "2345", "3456"];
|
||||
const largeStraightsArr = ["12345", "23456"];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,471 @@
|
||||
---
|
||||
id: 657e30e116d50c946b189925
|
||||
title: Step 85
|
||||
challengeType: 0
|
||||
dashedName: step-85
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user rolls a large straight, then the `Large straight` radio button option should be enabled with a score of `40` points.
|
||||
|
||||
Start by creating an `if` statement to check if `uniqueNumbersStr` is included in the `largeStraightsArr`. If so, call the `updateRadioOption` with `4` and `40` for the arguments.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `includes` method to check if `uniqueNumbersStr` is included in the `largeStraightsArr`.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*largeStraightsArr\.includes\(uniqueNumbersStr\)\s*\)\s*{?/);
|
||||
```
|
||||
|
||||
You should call your `updateRadioOption` with `3` and `30` for the arguments.
|
||||
|
||||
```js
|
||||
assert.match(code, /if\s*\(\s*largeStraightsArr\.includes\(uniqueNumbersStr\)\s*\)\s*{?\s*updateRadioOption\s*\(\s*4\s*,\s*40\s*\)\s*;?\s*}?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
const smallStraightsArr = ["1234", "2345", "3456"];
|
||||
const largeStraightsArr = ["12345", "23456"];
|
||||
|
||||
if (smallStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,467 @@
|
||||
---
|
||||
id: 657e37e29b45c39a98482860
|
||||
title: Step 86
|
||||
challengeType: 0
|
||||
dashedName: step-86
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the user does not get a small or large straight, call the `updateRadioOption` function and pass in the numbers `5` and `0` for the arguments.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `updateRadioOption` function and pass in the numbers `5` and `0` for the arguments.
|
||||
|
||||
```js
|
||||
assert.match(checkForStraights.toString(), /updateRadioOption\s*\(\s*5\s*,\s*0\s*\)\s*;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!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>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
const listOfAllDice = document.querySelectorAll(".die");
|
||||
const scoreInputs = document.querySelectorAll("#score-options input");
|
||||
const scoreSpans = document.querySelectorAll("#score-options span");
|
||||
const currentRoundText = document.getElementById("current-round");
|
||||
const currentRoundRollsText = document.getElementById("current-round-rolls");
|
||||
const totalScoreText = 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 totalScore = 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 = () => {
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
const smallStraightsArr = ["1234", "2345", "3456"];
|
||||
const largeStraightsArr = ["12345", "23456"];
|
||||
|
||||
if (smallStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
input.checked = false;
|
||||
});
|
||||
|
||||
scoreSpans.forEach((span) => {
|
||||
span.textContent = "";
|
||||
});
|
||||
};
|
||||
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
if (rolls === 3) {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(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();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
resetGame();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,21 +1,22 @@
|
||||
---
|
||||
id: 64b8c3f6f4dfc701661fab4f
|
||||
title: Step 52
|
||||
id: 657e390964da9f9bff8f3625
|
||||
title: Step 87
|
||||
challengeType: 0
|
||||
dashedName: step-52
|
||||
dashedName: step-87
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create a function named `updateScore` with 2 arguments named `selectedValue` and `achieved`. Then write a line of code that updates the totalScore variable by adding the integer value of the `selectedValue` argument to the `totalScore` variable.
|
||||
To see the results of your `checkForStraights` function, call your `checkForStraights` function inside the `rollDiceBtn` event listener and pass in the `diceValuesArr` variable for the argument.
|
||||
|
||||
Next, using the `innerHTMl` property, update the `totalScoreText` variable to display the `totalScore` variable. Finally, using the `innerHTML` property, set the `scoreHistory` to display `<li>${achieved} : ${selectedValue}</li>`
|
||||
And with that last change, you have completed your dice game!
|
||||
|
||||
# --hints--
|
||||
|
||||
TODO: add tests in follow up PR
|
||||
You should call the `checkForStraights` function and pass in the `diceValuesArr` variable for the argument.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkForStraights\s*\(\s*diceValuesArr\s*\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -282,7 +283,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -294,9 +295,90 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
const smallStraightsArr = ["1234", "2345", "3456"];
|
||||
const largeStraightsArr = ["12345", "23456"];
|
||||
|
||||
if (smallStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
@@ -309,33 +391,24 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -343,9 +416,14 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(diceValuesArr);
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
});
|
||||
|
||||
@@ -379,7 +457,6 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
updateStats();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
@@ -390,7 +467,6 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
@@ -655,7 +731,7 @@ const rollDice = () => {
|
||||
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];
|
||||
@@ -667,13 +743,91 @@ const updateStats = () => {
|
||||
currentRoundText.textContent = round;
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
|
||||
const updateScore = (selectedValue, achieved) => {
|
||||
totalScore += parseInt(selectedValue);
|
||||
totalScoreText.innerHTML = totalScore;
|
||||
totalScoreText.textContent = totalScore;
|
||||
|
||||
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 = diceValuesArr.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (highestCount >= 4) {
|
||||
updateRadioOption(1, sumOfAllDice);
|
||||
}
|
||||
|
||||
if (highestCount >= 3) {
|
||||
updateRadioOption(0, sumOfAllDice);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const detectFullHouse = (arr) => {
|
||||
const counts = {};
|
||||
|
||||
for (const num of arr) {
|
||||
counts[num] = counts[num] ? counts[num] + 1 : 1;
|
||||
}
|
||||
|
||||
const hasThreeOfAKind = Object.values(counts).includes(3);
|
||||
const hasPair = Object.values(counts).includes(2);
|
||||
|
||||
if (hasThreeOfAKind && hasPair) {
|
||||
updateRadioOption(2, 25);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const checkForStraights = (arr) => {
|
||||
const sortedNumbersArr = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbersArr = [...new Set(sortedNumbersArr)];
|
||||
const uniqueNumbersStr = uniqueNumbersArr.join("");
|
||||
|
||||
const smallStraightsArr = ["1234", "2345", "3456"];
|
||||
const largeStraightsArr = ["12345", "23456"];
|
||||
|
||||
if (smallStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
|
||||
if (largeStraightsArr.includes(uniqueNumbersStr)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
};
|
||||
|
||||
const resetRadioOption = () => {
|
||||
scoreInputs.forEach((input) => {
|
||||
input.disabled = true;
|
||||
@@ -685,33 +839,24 @@ const resetRadioOption = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateRadioOption = (optionNode, score) => {
|
||||
scoreInputs[optionNode].disabled = false;
|
||||
scoreInputs[optionNode].value = score;
|
||||
scoreSpans[optionNode].textContent = `, score = ${score}`;
|
||||
};
|
||||
const resetGame = () => {
|
||||
diceValuesArr = [0, 0, 0, 0, 0];
|
||||
score = 0;
|
||||
totalScore = 0;
|
||||
round = 1;
|
||||
rolls = 0;
|
||||
|
||||
const straightDetector = (arr) => {
|
||||
const sortNumbers = arr.sort((a, b) => a - b);
|
||||
const uniqueNumbers = [...new Set(sortNumbers)];
|
||||
const stringifyArray = uniqueNumbers.join("");
|
||||
listOfAllDice.forEach((dice, index) => {
|
||||
dice.textContent = diceValuesArr[index];
|
||||
});
|
||||
|
||||
const smallStraightLogic = ["1234", "2345", "3456"];
|
||||
const largeStraightLogic = ["12345", "23456"];
|
||||
totalScoreText.textContent = totalScore;
|
||||
scoreHistory.innerHTML = "";
|
||||
|
||||
if (smallStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(3, 30);
|
||||
}
|
||||
currentRoundRollsText.textContent = rolls;
|
||||
currentRoundText.textContent = round;
|
||||
|
||||
if (largeStraightLogic.includes(stringifyArray)) {
|
||||
updateRadioOption(4, 40);
|
||||
}
|
||||
|
||||
updateRadioOption(5, 0);
|
||||
}
|
||||
|
||||
const findRollResult = (arr) => {
|
||||
straightDetector(arr);
|
||||
resetRadioOption();
|
||||
};
|
||||
|
||||
rollDiceBtn.addEventListener("click", () => {
|
||||
@@ -719,9 +864,12 @@ rollDiceBtn.addEventListener("click", () => {
|
||||
alert("You have made three rolls this round. Please select a score.");
|
||||
} else {
|
||||
rolls++;
|
||||
resetRadioOption();
|
||||
rollDice();
|
||||
updateStats();
|
||||
findRollResult(diceValuesArr);
|
||||
getHighestDuplicates(diceValuesArr);
|
||||
detectFullHouse(diceValuesArr);
|
||||
checkForStraights(diceValuesArr);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -755,7 +903,6 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
updateStats();
|
||||
resetRadioOption();
|
||||
updateScore(selectedValue, achieved);
|
||||
|
||||
if (round > 6) {
|
||||
setTimeout(() => {
|
||||
alert(`Game Over! Your total score is ${totalScore}`);
|
||||
@@ -766,5 +913,4 @@ keepScoreBtn.addEventListener("click", () => {
|
||||
alert("Please select an option or roll the dice");
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user