WebDev 101 - Rock Paper Scissors project - button for both player value AND trigger playRound function


#1

Hello everyone,

I am currently reworking my Rock Paper Scissors project for the DOM manipulation lesson, and I ran into a problem with the double functionality of the buttons. They need to both assign a playerSelection value (namely, that of the button being pressed), and trigger the playRound() function (assigning a win, loss or tie based on the variables playerSelection and computerSelection).
Now, I can’t seem to return playerSelection before triggering the playRound() function, causing the outcome of the duel to be that of the current computerSelection value vs. the previous playerSelection value, and the current playerSelection value will be used the next duel, also resulting in an error during the first duel.
Before continuing, here is the code I believe to be relevant:

The body of my html:

<body>
    <h1>Rock Paper Scissors</h1>
    <div id="buttons">
        <button id="rock">Rock</button>
        <button id="paper">Paper</button>
        <button id="scissors">Scissors</button>
    </div>
    <div id="one-round">
        <div id="you"></div>
        <div id="computer"></div>
        <div id="result"></div>
    </div>
    <div id="final-block">
        <div id ="final-score"></div>
        <div id ="final-result"></div>
    </div>
</body>

The relevant JavaScript:

 let playerSelection;
 let playerSelectionString;
...
const btnR = document.querySelector('#rock');
    const btnP = document.querySelector('#paper');
    const btnS = document.querySelector('#scissors');

    btnR.addEventListener('click', (e) => {
        playerSelection = "Rock";
        playerSelectionString = "You chose: Rock";
        document.getElementById("you").textContent = playerSelectionString;
        playRound("Rock", computerSelection);
        return playerSelection;
    });
    btnP.addEventListener('click', (e) => {
        playerSelection = "Paper";
        playerSelectionString = "You chose: Paper";
        document.getElementById("you").textContent = playerSelectionString;
        playRound("Paper", computerSelection);
        return playerSelection;
    });
    btnS.addEventListener('click', (e) => {
        playerSelection = "Scissors";
        playerSelectionString = "You chose: Scissors";
        document.getElementById("you").textContent = playerSelectionString;
        playRound("Scissors", computerSelection);
        return playerSelection;
    });

Whenever I google my problem, I get suggestions on callbacks and promises. I tried the setTimeout() function, but unless I didn’t execute it well, it did not trigger the results I was hoping for. I don’t quite get the callbacks: I globally understand their function, but I can’t figure out whether they’re applicable to this situation, and if so, which particular function I should use. Which gives me the feeling that I’m researching answers far more complex than my current coding level can handle.

So my questions are: am I looking at this in the right way, or is my code just off? Which workaround for my problem would you suggest?
I’m happy to supply you with the full script if needed, but for clarity reasons I just selected the code I thought relevant. I’m sorry if this has been asked before, I saw a lot of topics on the project, but none seemed to address my issue.


#2

I had some similar issues. I don’t remember exactly how I solved them, but this is what I see in your code:

  • After player clicks a button, playerSelection is returned, not the winner. Instead, you could try returning the results of your call to your playRound function, which should return the winner.

  • Also, it doesn’t look like you’re passing computerSelection to your eventListener, so I don’t think that it’s getting passed into playRound either, but I can’t be sure without seeing all your code. If you find things still aren’t working after you try my first suggestion, you could try calling your function for generating computerSelection inside the event listener.

  • Finally, you could also try inserting a lot of console.logs to see what is happening. For example, a console.log(computerSelection) inside each eventListener function would let you know if computerSelection is getting passed to playRound when you call it inside your eventListener.

If this doesn’t help, can you also post your code for your playRound function?

Good luck!


#3

Thanks for your response! :slight_smile:
I was so confused with the non-sync answers, that I did not see that it was not the playerPlay() that was lagging behind, but the computerPlay() (facepalm). I should have included my full JS in the first place… Here is what I had written:

let computerSelection;
let computerSelectionString;
function computerPlay() {
        let computerNumber = Math.floor(Math.random()*3);
        if  (computerNumber == 1) {
            computerSelection = "Rock";
        } else if (computerNumber == 2) {
            computerSelection  = "Paper";
        } else {computerSelection = "Scissors";}
        computerSelectionString = ("The computer chose" + " " + computerSelection);
        document.getElementById("computer").textContent = computerSelectionString;
        return computerSelection;
        }
/* Old place of the playerPlay() function, left the variables here so they come earlier than playRound(), which requires them.*/
    let playerSelection;
    let playerSelectionString;

//Variables necessary for choosing a winner after five games (currently not in this JS file, will need rework)
    let win = 0;
    let loss = 0;
    let tie = 0;
    let roundString;

//Purpose: let the computer choose and declare a winner from the duel between computer and player
    function playRound(playerSelection, computerSelection) {
        computerPlay();

        if (playerSelection == "Rock" && computerSelection == "Scissors"
        || playerSelection == "Paper" && computerSelection == "Rock"
        || playerSelection == "Scissors" && computerSelection == "Paper") {
            roundString = ("Great job! " + playerSelection + " beats " + computerSelection + ".")
            document.getElementById("result").textContent = (roundString);
            return win++;
        } else if (playerSelection == "Rock" && computerSelection == "Paper"
        || playerSelection == "Paper" && computerSelection == "Scissors"
        || playerSelection == "Scissors" && computerSelection == "Rock") {
            roundString = ("Too bad! " + computerSelection + " beats " + playerSelection + ".")
            document.getElementById("result").textContent = (roundString);
            return loss++;
        } else if (playerSelection == computerSelection) {
            roundString = ("It's a tie!");
            document.getElementById("result").textContent = (roundString);
            return tie++;
        } else {
            roundString = ("Something went wrong!");
            document.getElementById("result").textContent = (roundString);
        }
    }

//New code replacing the old playerPlay() function
    const btnR = document.querySelector('#rock');
    const btnP = document.querySelector('#paper');
    const btnS = document.querySelector('#scissors');

    btnR.addEventListener('click', (e) => {
        playerSelection = "Rock";
        playerSelectionString = "You chose: Rock";
        document.getElementById("you").textContent = playerSelectionString;
        playRound("Rock", computerSelection);
        return playerSelection;
    });
    btnP.addEventListener('click', (e) => {
        playerSelection = "Paper";
        playerSelectionString = "You chose: Paper";
        document.getElementById("you").textContent = playerSelectionString;
        playRound("Paper", computerSelection);
        return playerSelection;
    });
    btnS.addEventListener('click', (e) => {
        playerSelection = "Scissors";
        playerSelectionString = "You chose: Scissors";
        document.getElementById("you").textContent = playerSelectionString;
        playRound("Scissors", computerSelection);
        return playerSelection;
    });

I now removed the computerPlay() function from playRound() and added it to the eventListeners:

btnR.addEventListener('click', (e) => {
        playerSelection = "Rock";
        playerSelectionString = "You chose: Rock";
        document.getElementById("you").textContent = playerSelectionString;
        computerPlay();
        playRound("Rock", computerSelection);
        return playerSelection;
    });

It now works! Thank you very much! :smiley: Let’s see if it keeps on working when I need to let it play for five rounds :’)


#4

Really glad to have been of help! A lot of my problems with js have been because I put a line of code in the wrong place.