JavaScript石头剪刀布游戏:实现得分达5分时终止游戏并停止计数器的技术问询
Fixing Your Rock-Paper-Scissors Game Termination Issue
Let's break down why your game isn't stopping when a player reaches 5 points, and fix it step by step.
Key Problems in Your Current Code
- Duplicate Event Listeners: You're binding click events to your buttons twice—once inside the
playRoundfunction, and again withbuttons.forEachat the bottom. This causes your game logic to run twice per click, leading to inconsistent score updates and termination checks. - Unnecessary For Loop: That
for(let i = 0; i < 5; i++)around your win condition check does nothing useful—it just repeats the same check 5 times without stopping the game. - No Game Lock After Win: Even if your win condition triggered, you never disabled the buttons or removed their event listeners, so players could keep clicking and adding points past 5.
- Mismatched Button IDs: Your HTML has buttons with IDs that don't match their text (e.g.,
<button id="scissors">paper</button>), and your JS selectors were picking the wrong buttons because of this—this was breaking your choice logic entirely!
Fixed Code Implementation
HTML (Fix Button ID/Text Mismatch)
First, correct your button IDs to match their labels:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Rock,Paper,Scissors</title> <link href="style.css" rel="stylesheet" type="text/css" /> </head> <body> <div> <div id="object container"> <button id="rock">Rock</button> <button id="paper">Paper</button> <button id="scissors">Scissors</button> </div> <!--result--> <div id="result">--</div> <!--counter board--> <div class="score-board"> <p class="player-score">0</p> <p>:</p> <p class="computer-score">0</p> </div> <!--player game played--> <div class="container"> <div> <p>player</p> <p class="player--game"></p> </div> <!--computer game played--> <div> <p>computer</p> <p class="computer--game"></p> </div> </div> </div> <script src="script.js"></script> </body> </html>
JavaScript (Refactored Logic with Termination)
This version cleans up redundant code, fixes the selector issues, and properly terminates the game when a player reaches 5 points:
const choices = ['rock', 'paper', 'scissors']; // Generate computer's random choice function getComputerChoice() { return choices[Math.floor(Math.random() * choices.length)]; } // DOM Elements const resultDisplay = document.querySelector('#result'); const rockBtn = document.querySelector('#rock'); const paperBtn = document.querySelector('#paper'); const scissorsBtn = document.querySelector('#scissors'); const playerGameLog = document.querySelector('.player--game'); const computerGameLog = document.querySelector('.computer--game'); const playerScoreDisplay = document.querySelector('.player-score'); const computerScoreDisplay = document.querySelector('.computer-score'); // Score Tracking let playerScore = 0; let computerScore = 0; // Check if game should end, and lock it if so function checkGameOver() { if (playerScore >= 5) { resultDisplay.textContent = "Player Wins the Game!"; disableGameButtons(); } else if (computerScore >= 5) { resultDisplay.textContent = "Computer Wins the Game!"; disableGameButtons(); } } // Remove event listeners to stop game play function disableGameButtons() { rockBtn.removeEventListener('click', handlePlayerChoice); paperBtn.removeEventListener('click', handlePlayerChoice); scissorsBtn.removeEventListener('click', handlePlayerChoice); } // Handle single round of play function handlePlayerChoice(e) { const playerChoice = e.target.id; const computerChoice = getComputerChoice(); // Update game logs playerGameLog.innerHTML += '<br><br>' + playerChoice; computerGameLog.innerHTML += '<br><br>' + computerChoice; // Determine round outcome if (playerChoice === computerChoice) { resultDisplay.textContent = "It's a tie!"; } else if ( (playerChoice === 'rock' && computerChoice === 'scissors') || (playerChoice === 'paper' && computerChoice === 'rock') || (playerChoice === 'scissors' && computerChoice === 'paper') ) { playerScore++; playerScoreDisplay.textContent = playerScore; resultDisplay.textContent = `${playerChoice} beats ${computerChoice}!`; } else { computerScore++; computerScoreDisplay.textContent = computerScore; resultDisplay.textContent = `${computerChoice} beats ${playerChoice}!`; } // Check for game end after each round checkGameOver(); } // Bind click events to buttons once rockBtn.addEventListener('click', handlePlayerChoice); paperBtn.addEventListener('click', handlePlayerChoice); scissorsBtn.addEventListener('click', handlePlayerChoice);
CSS (No Changes Needed)
Your existing CSS works fine, so you can keep it as is:
body { display: flex; justify-content: center; align-items: center; } button { padding: 1em; } #result { text-align: center; margin: 2em 0; } .container { display: flex; } p { margin: 1em; } .score-board { display: grid; grid-template-columns: repeat(4, 1fr); }
What Changed?
- Fixed Button Mismatch: Corrected HTML button IDs and JS selectors so your player choice logic works as intended.
- Single Event Binding: Removed duplicate event listeners to ensure each button click runs logic exactly once.
- Game Termination: Added
checkGameOver()that runs after every round—when a score hits 5, it shows the winner and removes button click listeners to prevent further play. - Cleaner Logic: Consolidated round handling into a single function instead of repeating code for each button.
内容的提问来源于stack exchange,提问作者callmeog
相关产品推荐
相关产品推荐

