diff --git a/RockPaperScissor/index.html b/RockPaperScissor/index.html new file mode 100644 index 0000000..69b245d --- /dev/null +++ b/RockPaperScissor/index.html @@ -0,0 +1,30 @@ + + + + + + + + Rock Paper Scissors + + + + + +
+

Rock Paper Scissors!

+

0 - 0

+
+
+
+
+
+

+ +

+ +
+
+ + + \ No newline at end of file diff --git a/RockPaperScissor/script.js b/RockPaperScissor/script.js new file mode 100644 index 0000000..4239ebb --- /dev/null +++ b/RockPaperScissor/script.js @@ -0,0 +1,105 @@ +const score = document.querySelector(".score"); +const selectionBtns = document.querySelectorAll("[data-selection]"); +const finalResult = document.querySelector(".final-result"); +const dialog = document.querySelector("dialog"); +const playAgainBtn = dialog.querySelector("button"); + +const CHOICE = { + ROCK: "Rock", + PAPER: "Paper", + SCISSORS: "Scissors", +}; +const ROUND_RESULT = { + PLAYER_WON: "playerWon", + COMPUTER_WON: "computerWon", + TIE: "tie", +}; + +let playerWins = 0; +let computerWins = 0; + +function play() { + const playerSelection = CHOICE[this.dataset.selection.toUpperCase()]; + const computerSelection = getComputerSelection(); + const result = playRound(playerSelection, computerSelection); + displayRoundResult(result, playerSelection, computerSelection); + updateScore(result); + displayScore(playerWins, computerWins); + if (playerWins === 5 || computerWins === 5) { + displayFinalResult(); + } +} + +function getComputerSelection() { + const possibleChoices = Object.values(CHOICE); + const randomIndex = Math.floor(Math.random() * possibleChoices.length); + return possibleChoices[randomIndex]; +} + +function playRound(playerSelection, computerSelection) { + if (playerSelection === computerSelection) { + return ROUND_RESULT.TIE; + } + const hasPlayerWon = + (playerSelection === CHOICE.ROCK && + computerSelection === CHOICE.SCISSORS) || + (playerSelection === CHOICE.PAPER && computerSelection === CHOICE.ROCK) || + (playerSelection === CHOICE.SCISSORS && computerSelection === CHOICE.PAPER); + return hasPlayerWon ? ROUND_RESULT.PLAYER_WON : ROUND_RESULT.COMPUTER_WON; +} + +function displayRoundResult(result, playerSelection, computerSelection) { + let textResult; + switch (result) { + case ROUND_RESULT.PLAYER_WON: + textResult = `You Win! ${playerSelection} beats ${computerSelection}`; + break; + case ROUND_RESULT.COMPUTER_WON: + textResult = `You Lose! ${computerSelection} beats ${playerSelection}`; + break; + default: + textResult = "Tie!"; + } + + const currentResult = document.querySelector(".round-result"); + const newResult = currentResult.cloneNode(); + newResult.textContent = textResult; + newResult.classList.add("hidden"); + currentResult.parentNode.replaceChild(newResult, currentResult); + // Trigger layout recalculation to show transition when the class + // is removed. + newResult.offsetWidth; + newResult.classList.remove("hidden"); +} + +function displayScore(playerWins, computerWins) { + score.textContent = `${playerWins} - ${computerWins}`; +} + +function displayFinalResult() { + finalResult.textContent = + playerWins === 5 + ? `You won ${playerWins} to ${computerWins}!!!` + : `You lost ${computerWins} to ${playerWins}!`; + dialog.showModal(); +} + +function updateScore(result) { + if (result === ROUND_RESULT.PLAYER_WON) { + playerWins++; + } else if (result === ROUND_RESULT.COMPUTER_WON) { + computerWins++; + } +} + +function reset() { + playerWins = 0; + computerWins = 0; + displayScore(playerWins, computerWins); + const roundResult = document.querySelector(".round-result"); + roundResult.textContent = ""; + dialog.close(); +} + +selectionBtns.forEach((btn) => btn.addEventListener("click", play)); +playAgainBtn.addEventListener("click", reset); \ No newline at end of file diff --git a/RockPaperScissor/style.css b/RockPaperScissor/style.css new file mode 100644 index 0000000..2866e24 --- /dev/null +++ b/RockPaperScissor/style.css @@ -0,0 +1,179 @@ + + +:root { + --blue-ncs: #2589bd; + --selective-yellow: #ffb800; + --dark-purple: #27233a; +} + +html { + box-sizing: border-box; + font-family: "Press Start 2P", cursive; + color: var(--selective-yellow); + -webkit-text-stroke: 1px var(--dark-purple); +} + +html, +body { + width: 100%; + height: 100%; +} + +*, +*::before, +*::after { + box-sizing: inherit; + margin: 0; +} + +button { + padding: 0.5em 1.5em; + cursor: pointer; + color: var(--dark-purple); + background-color: var(--selective-yellow); + border: 1px solid var(--dark-purple); + border-radius: 4px; + transition: transform 0.1s ease-out; +} + +button:hover { + background-color: #ff9500; + transition: background-color 0.3s ease-out, transform 0.1s ease-out; +} + +button:active { + transform: scale(0.95); +} + +dialog { + position: fixed; + inset: 0; + margin: auto; + padding: 1rem; + display: flex; + flex-direction: column; + align-items: center; + max-width: min(90%, 24ch); + pointer-events: none; + font-family: "Press Start 2P", cursive; + color: var(--selective-yellow); + -webkit-text-stroke: 1px var(--dark-purple); + background-color: var(--blue-ncs); + border: 1px solid var(--dark-purple); + border-radius: 4px; + box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); + transform: scale(0.5); + opacity: 0; + transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out; +} + +dialog[open] { + pointer-events: all; + transform: scale(1); + opacity: 1; +} + +dialog::backdrop { + background-color: rgba(0, 0, 0, 0.3); +} + +body { + background-color: var(--blue-ncs); + padding: 1rem; +} + +main { + max-width: 900px; + display: flex; + flex-direction: column; + justify-items: center; + margin: 0 auto; +} + +h1 { + text-align: center; + font-size: 3.5rem; + margin-top: 25vmin; + line-height: 1.3; +} + +.score { + margin-top: 1.5rem; + font-size: 2.5rem; + text-align: center; +} + +.selections { + display: flex; + justify-content: center; + gap: 3rem; +} + +.selection-wrapper { + display: inline-block; + transform: scale(0.8); + opacity: 0.6; + transition: transform 0.3s ease-out, opacity 0.3s ease-out; +} + +.selection-wrapper:hover { + transform: scale(1); + opacity: 1; +} + +.selections button { + font-size: 5rem; + background: none; + border: none; + padding: 0; + transition: transform 10ms ease-out; +} + +.selections button:active { + transform: translateY(2px); +} + +.round-result { + margin-top: 3rem; + position: relative; + top: 0; + transition: top 0.3s ease-in-out, opacity 0.3s ease-in-out; +} + +.hidden { + opacity: 0; + top: 1rem; +} + +.game-end-modal button { + margin-top: 1rem; +} + +.final-result { + text-align: center; + line-height: 1.5; +} + +@media only screen and (max-width: 650px) { + html { + font-size: 13px; + } + + h1 { + margin-top: 34vmax; + } +} + +@media only screen and (max-width: 490px) { + h1 { + font-size: 2.5rem; + } + + .score { + font-size: 1.5rem; + } + + .selections button { + font-size: 4rem; + } +} \ No newline at end of file