剪刀石头布:第一轮分数保持为0

Rock, Paper, Scissors: Scores remain at 0 on the first round

从我乱七八糟的代码可以看出,我在JavaScript上还是个初学者,所以如果这会伤害你的眼睛,我真的很抱歉。

我正在研究来自 The Odin Project 的剪刀石头布项目,我们将通过应用 DOM 方法向其中添加一个简单的 UI。老实说,我真的不知道我这样做对不对。我觉得 if 语句不应该在事件侦听器中,但这是我发现使分数统计有效的唯一方法。通过将代码放在这里,我让它可以播放,但不太正确:

let playerScore = 0;
let computerScore = 0;
let scores = document.createElement('p');
let body = document.querySelector('body');
const results = document.createElement('div');
body.appendChild(results);

const buttons = document.querySelectorAll('button');
buttons.forEach((button) => {
    button.addEventListener('click', () => {
        let playerSelection = button.className;
        let computerSelection = computerPlay();
        let roundResult =  playRound(playerSelection, computerSelection);
        console.log(roundResult);
        score();
        gameEnd();
        if (roundResult === 'playerWin') {
            playerScore++;
        } else if (roundResult === 'computerWin') {
            computerScore++;
        }
    })
})

//computer pick
function computerPlay() {
    const pick = ['rock', 'paper', 'scissors'];
    return pick[Math.floor(Math.random() * pick.length)];
}

// Round Play
function playRound(playerSelection, computerSelection) {
    //message that specifies the winner
    let tie = `It's a tie you both picked ${playerSelection}`;
    let playerWin = `You win this round! ${playerSelection} beats ${computerSelection}`;
    let computerWin = `You lose this round! ${computerSelection} beats 
    ${playerSelection}`;

    if(playerSelection === computerSelection) {
        results.innerHTML = tie;
        return 'tie';
    } else if (playerSelection === 'rock' && computerSelection === 'scisors') {
        results.innerHTML = playerWin;
        return 'playerWin';
    } else if (playerSelection === 'paper' && computerSelection === 'rock') {
        results.innerHTML = playerWin;
        return 'playerWin';
    } else if (playerSelection === 'scissors' && computerSelection === 'paper') {
        results.innerHTML = playerWin;
        return 'playerWin';
    } else {
        results.innerHTML = computerWin;
        return 'computerWin';
    }
}

function score() {
    //new element where score would be seen
    scores.innerHTML = `player: ${playerScore} | computer: ${computerScore}`; 
    body.appendChild(scores); 
}

function gameEnd() {
    if(playerScore === 5 || computerScore === 5) {
        document.querySelector('.rock').disabled = true;
        document.querySelector('.paper').disabled = true;
        document.querySelector('.scissors').disabled = true;
        if (playerScore > computerScore) {
            alert('You win the game');
        } else if (computerScore > playerScore) {
            alert('Aww you lose');
        }
    }
}
<button class="rock">Rock</button>
<button class="paper">Paper</button>
<button class="scissors">Scissors</button>

问题来了,第一轮过后分数都是0。它会显示谁是获胜者,但在我选择下一轮之前它不会计算分数。我到底哪里出了问题? (如果我的解释听起来像我的代码一样令人困惑,我真的很抱歉。)

无论如何,在应用 DOM 方法之前,这就是初始代码的样子。 我最初尝试使用这段代码,但我什至无法用这段代码计算分数,因为我似乎无法获得函数 playRound() 的 return 值。

function computerPlay() {
const pick = ['rock', 'paper', 'scissors'];
return pick[Math.floor(Math.random() * pick.length)];
}

function playRound(playerSelection, computerSelection) {
 if (playerSelection === computerSelection) {
    alert(`It's a tie! you both picked ${playerSelection}`);
    return "tie";
 } else if (playerSelection !== "rock" && playerSelection !== "paper" && 
   playerSelection !== "scissors"){
    alert(`You sure about using ${playerSelection} on a game of "Rock, Paper, 
    Scissors"?`)
 } else if (playerSelection === "rock" && computerSelection === "scissors") {
    alert(`You win this round! ${playerSelection} beats ${computerSelection}`);
    return "playerWin";
 } else if (playerSelection === "paper" && computerSelection === "rock") {
    alert(`You win this round! ${playerSelection} beats ${computerSelection}`);
    return "playerWin";
 } else if (playerSelection === "scissors" && computerSelection === "paper") {
    alert(`You win this! ${playerSelection} beats ${computerSelection}`);
    return "playerWin";
 } else {
    alert(`You lose this round! ${computerSelection} beats ${playerSelection}`);
    return "botWin";
 }
}

const computerSelection = computerPlay();

// to loop the game until 5 rounds
function game() {
  let playerScore = 0;
  let botScore = 0;
  let gameWinner = '';

   for (let i = 0; i < 5; i++) {

    let playerSelection = prompt(`Round ${i+1}: Choose among "Rock, Paper, Scissors" 
      as your weapon`).toLowerCase();
    let roundResult = playRound(playerSelection, computerPlay());

    if (roundResult === "playerWin" ) {
      playerScore++;
    } else if (roundResult === "botWin" ) {
      botScore++;
    }
  }

  if (playerScore > botScore) {
    gameWinner = 'You win!';
  } else if (botScore > playerScore) {
    gameWinner = 'You lose, Computer wins!';
  } else {
    gameWinner = 'Draw';
  }

  alert(`Player: ${playerScore}  |  Bot: ${botScore}`);

 if (gameWinner === 'Draw') {
    alert("There is no match winner, draw!");
 } else {
    alert(`${gameWinner}`);
 }
}

game();

在这些代码之间,哪个更有可能被修复?还是完全扔掉这段代码并重新开始会更好?

问题出在这部分代码:

        score();
        gameEnd();
        if (roundResult === 'playerWin') {
            playerScore++;
        } else if (roundResult === 'computerWin') {
            computerScore++;
        }

score()会在HTML页面更新分数,但此时分数还没有更新。这只会在 if ... else if 块的后面发生。

所以解决方法是更新分数,然后调用score():

        score();
        gameEnd();
        if (roundResult === 'playerWin') {
            playerScore++;
        } else if (roundResult === 'computerWin') {
            computerScore++;
        }

还有一个与此相关的问题:在游戏结束时(当玩家达到5分时),gameEnd()会调用alert。但是 alert 不允许页面实际显示最新的更改。相反,它会阻止对其进行任何更新。我会在 HTML 元素中显示 game-over 消息,而不是在 alert 中,就像您已经为分数所做的那样。或者,您可以使用计时器延迟 alert 的执行,但我会避免使用 alert.

这是您可以在当前使用 alert 的函数 gameEnd 中执行的操作:

        if (playerScore > computerScore) {
            results.innerHTML += '<p><b>You win the game</b>';
        } else if (computerScore > playerScore) {
            results.innerHTML += '<p><b>Aww you lose</b>';
        }