Skip to content

Rock, Paper, Scissors game using Javascript

I’m attempting a Rock, Paper, Scissors game using Javascript. I’m new to Javascript, so I don’t know much. Each time I click a button I can get the values both for playerSelection and computerSelection but when I try to run the function playRound() it seems like it can’t “reach” the values returned by clicking the buttons. What am I doing wrong?

const selectionButtons = document.querySelectorAll('[data-selection]')
const options = ['rock', 'paper', 'scissors']

function computerPlay() {
 const random = options[Math.floor(Math.random() * options.length)]; 
 console.log(random)
 return random
}

function playerSelection() {
  selectionButtons.forEach(selectionButton => {
    selectionButton.addEventListener('click', e => {
    const selected = selectionButton.dataset.selection
    console.log(selected)
    return selected
    })
  })
}

function computerSelection() {
  selectionButtons.forEach(selectionButton => {
    selectionButton.addEventListener('click', e => {
    computerPlay()
    })
  })
}

const playerSelected = playerSelection()
const computerSelected = computerSelection()

function playRound() {
  if (playerSelected == 'rock' && computerSelected == 'rock' ||
      playerSelected == 'paper' && computerSelected == 'paper' ||
      playerSelected == 'scissors' && computerSelected == 'scissors') {
      console.log('tie')
  }
  else if (playerSelected == 'rock' && computerSelected == 'scissors' ||
           playerSelected == 'paper' && computerSelected == 'rock' ||
           playerSelected == 'scissors' && computerSelected == 'paper') {
           console.log('player won') 
           }
  else {
    console.log('player lose')
  }
}

playRound()
* {
    font-style: arial;
    background-color: lightblue;
    margin:0;
    padding:0;
}

.scores {
    display:grid;
    grid-template-columns: repeat(2, 1fr);
    justify-items: center;
    justify-content: center;
    align-items: center;
    margin-top: 2rem;
}


.selection {
    cursor: pointer;
    background-color: red;
    font-size: 1rem;
    transition:500ms;
}

.selection:hover {
    transform: scale(1.3)
}

.header {
    text-align: center;
    margin-top:0;
    font-size: 2rem;
}

.selections {
    display: flex;
    justify-content: space-around;
    margin-top: 5rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
    <script src="script.js" defer></script>
</head>
<body>
<div class="header">
Choose your option:
</div>
<div class="selections">
<button class="selection" data-selection="rock">Rock</button>
<button class="selection" data-selection="paper">Paper</button>
<button class="selection" data-selection="scissors">Scissors</button>
</div>
<div class="scores">
<div>
    Player Score
    <span>0</span>
</div>
<div>
    Computer Score
    <span>0</span>      
</div>      

</body>
</html>

Answer

There are a couple issues here. First off, you are calling the playRound() function before any buttons are pressed. It’s called on load of the script and then never again. What you’d need to do is to call playRound() inside your click handler because that is the event which you need to test if the user won, lost, or tied.

Secondly, you are trying to return values from a click handler inside a .forEach, neither of which by definition return a value to their caller.

I think your best bet to solve this is to do a couple things:

  1. Move your computerPlay() into your click handler
  2. Move your playRound() into your click handler

Here’s an example of what it would look like:

const selectionButtons = document.querySelectorAll('[data-selection]')
const options = ['rock', 'paper', 'scissors']

function computerPlay() {
 const random = options[Math.floor(Math.random() * options.length)]; 
 return random
}

selectionButtons.forEach(selectionButton => {
  selectionButton.addEventListener('click', e => {
  const selected = selectionButton.dataset.selection;
  const computerSelected = computerPlay();
  console.log("Player Selection: " + selected); 
  console.log("Computer Selection: " + computerSelected); 
  playRound(selected, computerSelected);
  })
})

function playRound(playerSelected, computerSelected) {
  if (playerSelected == 'rock' && computerSelected == 'rock' ||
      playerSelected == 'paper' && computerSelected == 'paper' ||
      playerSelected == 'scissors' && computerSelected == 'scissors') {
      console.log('tie')
  }
  else if (playerSelected == 'rock' && computerSelected == 'scissors' ||
           playerSelected == 'paper' && computerSelected == 'rock' ||
           playerSelected == 'scissors' && computerSelected == 'paper') {
           console.log('player won') 
           }
  else {
    console.log('player lose')
  }
}
* {
    font-style: arial;
    background-color: lightblue;
    margin:0;
    padding:0;
}

.scores {
    display:grid;
    grid-template-columns: repeat(2, 1fr);
    justify-items: center;
    justify-content: center;
    align-items: center;
    margin-top: 2rem;
}


.selection {
    cursor: pointer;
    background-color: red;
    font-size: 1rem;
    transition:500ms;
}

.selection:hover {
    transform: scale(1.3)
}

.header {
    text-align: center;
    margin-top:0;
    font-size: 2rem;
}

.selections {
    display: flex;
    justify-content: space-around;
    margin-top: 5rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
    <script src="script.js" defer></script>
</head>
<body>
<div class="header">
Choose your option:
</div>
<div class="selections">
<button class="selection" data-selection="rock">Rock</button>
<button class="selection" data-selection="paper">Paper</button>
<button class="selection" data-selection="scissors">Scissors</button>
</div>
<div class="scores">
<div>
    Player Score
    <span>0</span>
</div>
<div>
    Computer Score
    <span>0</span>      
</div>      

</body>
</html>