Back to Freecodecamp

Step 10

curriculum/challenges/english/blocks/review-algorithmic-thinking-by-building-a-dice-game/657d4a7e2002f822c646204b.md

latest10.0 KB
Original Source

--description--

After a user makes a selection, they should be able to keep that score and move onto the next round by clicking the keepScoreBtn.

When that button is clicked, you should find which radio option is checked and capture its value and id attributes. If the user has selected an option, call your functions to update the score, reset the radio options, and add the value and id to the score history.

If the user has not selected an option, display an alert informing them to do so.

--hints--

When your keepScoreBtn is clicked, the score should be updated in the totalScoreElement text.

js
scoreInputs[0].checked = true;
scoreInputs[0].value = "10";
score = 10;
keepScoreBtn.click();
assert.strictEqual(totalScoreElement.innerText, "20");

When your keepScoreBtn is clicked, the radio options should be reset.

js
scoreInputs[0].checked = true;
scoreInputs[0].value = "10";
score = 10;
keepScoreBtn.click();
for (const element of scoreInputs) {
  assert.isFalse(element.checked);
  assert.isTrue(element.disabled);
}
for (const element of scoreSpans) {
  assert.strictEqual(element.innerText, "");
}

When your keepScoreBtn is clicked, the score history should be updated.

js
scoreInputs[0].checked = true;
scoreInputs[0].value = "10";
scoreHistory.innerHTML = "";
keepScoreBtn.click();
assert.strictEqual(scoreHistory.innerHTML, "<li>three-of-a-kind : 10</li>");

When your keepScoreBtn is clicked, and no options are selected, you should display an alert to the user.

js
const messages = []
const oldAlert = alert;
alert = (msg) => {messages.push(msg)};
const oldWindow = window.alert;
window.alert = (msg) => {messages.push(msg)};
keepScoreBtn.click();
assert.lengthOf(messages, 1);

--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 roundElement = document.getElementById("current-round");
const rollsElement = document.getElementById("current-round-rolls");
const totalScoreElement = document.getElementById("total-score");
const scoreHistory = document.getElementById("score-history");
const rollDiceBtn = document.getElementById("roll-dice-btn");
const keepScoreBtn = document.getElementById("keep-score-btn");
const rulesContainer = document.querySelector(".rules-container");
const rulesBtn = document.getElementById("rules-btn");

let diceValuesArr = [];
let isModalShowing = false;
let score = 0;
let round = 1; 
let rolls = 0; 

const rollDice = () => {
  diceValuesArr = [];

  for (let i = 0; i < 5; i++) {
    const randomDice = Math.floor(Math.random() * 6) + 1;
    diceValuesArr.push(randomDice);
  };

  listOfAllDice.forEach((dice, index) => {
    dice.textContent = diceValuesArr[index];
  });
};

const updateStats = () => {
  rollsElement.textContent = rolls;
  roundElement.textContent = round;
};

const updateRadioOption = (index, score) => {
  scoreInputs[index].disabled = false;
  scoreInputs[index].value = score;
  scoreSpans[index].textContent = `, score = ${score}`;
};

const updateScore = (selectedValue, achieved) => {
  score += parseInt(selectedValue);
  totalScoreElement.textContent = score;

  scoreHistory.innerHTML += `<li>${achieved} : ${selectedValue}</li>`;
};

const getHighestDuplicates = (arr) => {
  const counts = {};

  for (const num of arr) {
    if (counts[num]) {
      counts[num]++;
    } else {
      counts[num] = 1;
    }
  }

  let highestCount = 0;

  for (const num of arr) {
    const count = counts[num];
    if (count >= 3 && count > highestCount) {
      highestCount = count;
    }
    if (count >= 4 && count > highestCount) {
      highestCount = count;
    }
  }

  const sumOfAllDice = arr.reduce((a, b) => a + b, 0);

  if (highestCount >= 4) {
    updateRadioOption(1, sumOfAllDice);
  }

  if (highestCount >= 3) {
    updateRadioOption(0, sumOfAllDice);
  }

  updateRadioOption(5, 0);
};

const resetRadioOptions = () => {
  scoreInputs.forEach((input) => {
    input.disabled = true;
    input.checked = false;
  });

  scoreSpans.forEach((span) => {
    span.textContent = "";
  });
};

rollDiceBtn.addEventListener("click", () => {
  if (rolls === 3) {
    alert("You have made three rolls this round. Please select a score.");
  } else {
    rolls++;
    resetRadioOptions();
    rollDice();
    updateStats();
    getHighestDuplicates(diceValuesArr);
  }
});

rulesBtn.addEventListener("click", () => {
  isModalShowing = !isModalShowing;

  if (isModalShowing) {
    rulesBtn.textContent = "Hide rules";
    rulesContainer.style.display = "block";
  } else {
    rulesBtn.textContent = "Show rules";
    rulesContainer.style.display = "none";
  }
});

--fcc-editable-region--

--fcc-editable-region--