Home > Back-end >  Rock, Paper, Scissors: Scores remain at 0 on the first round
Rock, Paper, Scissors: Scores remain at 0 on the first round

Time:05-03

As you can tell by my messy code, I am still a beginner at JavaScript so I'm really sorry If this will hurt your eyes.

I am working on this Rock, Paper, Scissors project from The Odin Project where we would add a simple UI to it by applying DOM Methods. To be honest, I really don't know if I'm doing this right. I feel like the if statements shouldn't be inside the event listener but this is the only way I have found to make the tallying of scores work. By putting the code here I made it playable, but not quite right:

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 >Rock</button>
<button >Paper</button>
<button >Scissors</button>

Here's the problem, scores remain both at 0 after the first round. It would show who the winner is but it won't tally its score until I have picked for the next round. Where exactly did I go wrong with this one? (feels like in everything I'm genuinely sorry if my explanation sounds as confusing as my code.)

Anyways this is what the initial code looks like, before applying the DOM Methods. I was initially trying to use this code but I cant even tally the scores with this one because I can't seem to get the return value of of the function playRound().

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();

between these codes which is more likely to be fixed? or would it be better to completely throw this code and just start anew?

CodePudding user response:

The problem is in this part of the code:

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

score() will update the score in the HTML page, but at that moment the scores have not been updated yet. That only happens later in that if ... else if block.

So the solution is to first update the score, and then to call score():

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

There is another issue related to this: at the end of the game (when a player reaches 5 points), gameEnd() will call alert. But alert does not allow the page to actually display the latest changes. Instead it blocks any update to it. I would display the game-over message in an HTML element instead of in an alert, just like you already do for the scores. Alternatively, you could delay the execution of alert with a timer, but I would just avoid using alert.

Here is what you can do in the function gameEnd where you currently use alert:

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