I started studying web development a few months ago and to practice my skills I decided to do the game of rock, paper, scissors.
Here are some questions for review:
- Is the use of HTML semantics correct and how could I improve it?
- How could I improve the CSS and JavaScript code in terms of readability, optimization and best practices?
- Are the class, functions and variable names correct (I am not a native English speaker and I am learning, so there may be things misspelled)?
- Is the style of the code correct?
Code:
let counter_rounds = 0; let player_wins = 0; let computer_wins = 0; let draws = 0; const ROUNDS_PER_GAME = 3; const choices = ["ROCK", "PAPER", "SCISSORS"]; const score_human = document.querySelector(".score-human"); const score_computer = document.querySelector(".score-computer"); const result_round = document.querySelector(".result-round"); const result_human = document.querySelector(".result-human"); const final_result = document.querySelector(".final-result"); const result_computer = document.querySelector(".result-computer"); const image_container_player = document.querySelector(".player-choose .image-container"); const image_container_computer = document.querySelector(".computer-choose .image-container"); const buttons = document.querySelector(".buttons-container"); const new_game_button = document.querySelector(".new-game-button"); buttons.addEventListener("click", play); new_game_button.addEventListener("click", reset_game); function play(event) { counter_rounds++; let player, computer; if ( event.target.classList.contains("btn") || event.target.closest(".button-container") && counter_rounds < 3 ) { const button_value = event.target .closest(".button-container") .getAttribute("data-value"); player = choices.indexOf(button_value); computer = Math.floor(Math.random() * 3); check_winner_round(player, computer); } if (counter_rounds === ROUNDS_PER_GAME) { disable_buttons(); check_winner_game(); new_game_button.style.display = "block"; } } function check_winner_round(player, computer) { if (player === computer) { result_round.textContent = "It's a draw."; result_human.textContent = `You chose ${choices[player]}.`; result_computer.textContent = `Computer choose ${choices[computer]}.`; draws++; } else if ((player-computer+3) % 3 === 1) { score_human.textContent = Number(score_human.textContent) + 1; result_round.textContent = "You won."; result_human.textContent = `You chose ${choices[player]}.`; result_computer.textContent = `Computer chose ${choices[computer]}.`; player_wins++; } else { score_computer.textContent = Number(score_computer.textContent) + 1; result_round.textContent = "You lost."; result_human.textContent = `You chose ${choices[player]}.`; result_computer.textContent = `Computer chose ${choices[computer]}.`; computer_wins++; } update_image_containers(player, computer); } function check_winner_game() { if (player_wins === computer_wins) final_result.textContent = "It's a draw."; else if (player_wins > computer_wins) final_result.textContent = "You won the set."; else final_result.textContent = "Computer wins the set."; } function update_image_containers(player, computer) { const image_player = `img/${choices[player].toLowerCase()}.png`; const image_computer = `img/${choices[computer].toLowerCase()}.png`; image_container_player.style.backgroundImage = `url(${image_player})`; image_container_computer.style.backgroundImage = `url(${image_computer})`; image_container_player.classList.remove("empty"); image_container_computer.classList.remove("empty"); } function reset_image_containers() { image_container_player.classList.add("empty"); image_container_computer.classList.add("empty"); image_container_player.style.backgroundImage = ""; image_container_computer.style.backgroundImage = ""; } function set_buttons_state(disabled) { const buttonContainer = document.querySelector(".buttons-container"); buttonContainer.classList.toggle("disabled", disabled); } function disable_buttons() { set_buttons_state(true); } function enable_buttons() { set_buttons_state(false); } function reset_game() { score_human.textContent = 0; score_computer.textContent = 0; result_round.textContent = ""; result_human.textContent = ""; result_computer.textContent = ""; final_result.textContent = ""; player_wins = 0; computer_wins = 0; draws = 0; counter_rounds = 0; reset_image_containers(); enable_buttons(); new_game_button.style.display = "none"; }
*, *::before, *::after { box-sizing: border-box; padding: 0; margin: 0; } body { background-color: #000; max-height: 100vh; } header { margin-top: 20px; margin-bottom: 20px; } h1 { color: #f3ffff; text-align: center; } .scoreboard { display: grid; grid-template-columns: repeat(2, 1fr); justify-items: center; align-items: center; background-color: #014689; height: 150px; width: 400px; margin: 0 auto; border: 4px solid #f3ffff; border-radius: 20px; } .player-score, .computer-score { display: flex; flex-direction: column; justify-content: space-around; height: inherit; width: 100px; } .player, .computer { color: #f3ffff; font-weight: bold; font-size: 25px; text-decoration: underline #f3ffff; display: flex; justify-content: center; align-items: center; } .score-computer, .score-human { background-color: #000; border: 4px solid #f3ffff; border-radius: 10px; color: #ea4225; font-family: 'Seven Segment', sans-serif; font-weight: bold; font-size: 55px; display: flex; justify-content: space-around; align-items: center; } .game-board-container { display: flex; justify-content: center; align-items: center; height: 385px; max-width: 100vw; padding-left: 10%; padding-right: 10%; } .game-board { display: flex; justify-content: center; align-items: center; } .player-choose p, .computer-choose p { color: #ffd700; font-weight: bold; font-size: 25px; text-decoration: underline #ffd700; } .circle { background-color: #87ceeb; border: 3px solid #3b83bd; border-radius: 50%; height: 250px; width: 250px; margin-top: 20px; } .image-container { background-repeat: no-repeat; background-size: 80% 80%; background-position: center; height: 100%; width: 100%; } .vs-image { background-repeat: no-repeat; background-size: 100% 100%; background-position: center; height: 200px; width: 200px; } .game-play p { font-family: 'Proxima Nova', sans-serif; font-weight: bold; text-align: center; } .win-condition { color: #f5f5dc; font-size: 18px; } .round-results { color: #f3ffff; font-size: 20px; margin-top: 20px; margin-bottom: 50px; } .choose-option { font-family: 'Proxima Nova', sans-serif; font-weight: bold; font-size: 25px; color: red; } .buttons-container { display: flex; justify-content: center; max-width: 100vw; margin-top: 10px; } .button-container { background-color: #014689; width: 150px; height: 70px; padding: 20px; margin-left: 20px; border-radius: 5px; cursor: pointer; } .btn { background: none; border: 0; color: #f3ffff; cursor: pointer; font: inherit; font-weight: bold; line-height: normal; overflow: visible; width: 100%; height: 100%; display: flex; align-items: center; justify-content: space-evenly; padding: 0 10px; } .btn img { width: 50px; height: 50px; background-color: transparent; } .image-container.empty { background: none; } .new-game-button { background-color: #014689; border-radius: 5px; width: 130px; cursor: pointer; display: none; margin: 0 auto; margin-top: 10px; } .disabled { opacity: 0.5; pointer-events: none; cursor: not-allowed; }
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Rock, Paper, Scissors</title> <link rel="stylesheet" href="css/styles.css" /> <link href="https://fonts.cdnfonts.com/css/seven-segment" rel="stylesheet" /> <link href="https://fonts.cdnfonts.com/css/proxima-nova-2" rel="stylesheet" /> </head> <body> <header><h1>Rock, Paper, Scissors</h1></header> <main> <section class="scoreboard"> <div class="player-score"> <p class="player">PLAYER</p> <p class="score-human">0</p> </div> <div class="computer-score"> <p class="computer">COMPUTER</p> <p class="score-computer">0</p> </div> </section> <section class="game-board-container"> <div class="game-board"> <div class="player-choose"> <p class="player">PLAYER</p> <div class="circle"> <div class="image-container empty"></div> </div> </div> <img src="img/vs.png" class="vs-image" /> <div class="computer-choose"> <p class="computer">COMPUTER</p> <div class="circle"> <div class="image-container empty"></div> </div> </div> </div> </section> <section class="game-play"> <p class="win-condition">The best score out of 3 is the winner.</p> <div class="round-results"> <p class="result-human"></p> <p class="result-computer"></p> <p class="result-round"></p> <p class="final-result"></p> <button class="btn new-game-button">New Game</button> </div> <p class="choose-option">Choose an option:</p> <div class="buttons-container"> <div class="button-container" data-value="ROCK"> <button class="btn game-button"> <img src="img/rock_emoji.png" alt="rock_button"> Rock </button> </div> <div class="button-container" data-value="PAPER"> <button class="btn game-button"> <img src="img/paper_emoji.png" alt="paper_button" data-value="PAPER"> Paper </button> </div> <div class="button-container" data-value="SCISSORS"> <button class="btn game-button"> <img src="img/scissors_emoji.png" alt="scissors_button" data-value="SCISSORS"> Scissors </button> </div> </div> </section> </main> <script src="js/script.js"></script> </body> </html>