-1

I am trying to create a function called game() that will prompt a user to input text of 'rock', 'paper', or 'scissor'. That input text will be assigned to const playerSelection. Following that, a const computerSelection will pull a random hand signal from my getComputerChoice() function.

When those two values are evaluated, function playRound() will be invoked passing the playerSelection and computerSelection arguments into playRound(). However, the console is throwing an Uncaught ReferenceError: playerSelection is not defined error in the first line of the playRound() function.

I thought defining the playerSelection before the playRound() is invoked would be correct, but I can't figure out why it's saying it's not defined.

I apologize if my code is unwieldy. I am a fresh novice. =]

function getComputerChoice() {
  let computerChoice = Math.floor(Math.random() * 3);      
  if (computerChoice === 0) {
    return 'rock';   
  } else if (computerChoice === 1) {
    return 'paper';    
  } else if (computerChoice === 2) {
    return 'scissor';
  }
}

function playRound() {
  if (playerSelection === computerSelection) {
    return 'Draw!';
  } else if (playerSelection === 'rock' && computerSelection === 'scissor') {
    return 'You Win! Rock beats Scissor';
  } else if (playerSelection === 'rock' && computerSelection === 'paper') {
    return 'You Lose! Paper beats Rock';
  } else if (playerSelection === 'paper' && computerSelection === 'rock') {
    return 'You Win! Paper beats Rock';
  } else if (playerSelection === 'paper' && computerSelection === 'scissor') {
    return 'You Lose! Scissor beats Paper';
  } else if (playerSelection === 'scissor' && computerSelection === 'paper') {
    return 'You Win! Scissor beats Paper';
  } else if (playerSelection === 'scissor' && computerSelection === 'rock') {
    return 'You Lose! Rock beats Scissor';
  } return 'Invalid input';

}


function game() {
  const playerSelection = prompt("Choose hand signal", "");
  const computerSelection = getComputerChoice();
  console.log(computerSelection);
  
  playRound() 
 
}
game();
jabaa
  • 5,844
  • 3
  • 9
  • 30
M Codet
  • 57
  • 5
  • 1
    _"passing the playerSelection and computerSelection arguments into playRound()"_ - only you totally forgot to actually _do_ that, pass the values. Your declaration of `function playRound()` does not explicitly _take_ any parameters at this point, and neither are you passing any when you call the function, `playRound()` – CBroe Feb 28 '23 at 11:22
  • 1
    [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) - _"The const declaration creates block-scoped constants"_ – Diego D Feb 28 '23 at 11:23
  • 1
    Not efficient at all when you have to type the words `paper`, `scissor` or `rock` you could have made it a ratio input – Chris G Feb 28 '23 at 11:24
  • Oh, wow. I thought even without having parameters. but by having the variable names in the conditions within playRound(), passing identically named variables would still understood by the engine. I am now guessing this is completely wrong and I always need to include parameters? @CBroe – M Codet Feb 28 '23 at 11:26
  • Would you be able to expound on that? I am doing google searches but nothing javascript related comes up besides input boxes in regards to ratio inputs. I don't believe I have come across this yet in my learning course. @ChrisG – M Codet Feb 28 '23 at 11:29
  • Radio buttons would be HTML elements, that your JS interacts with. So more a "web page"-style implementation of the whole thing, rather than handling this via UI dialogs like `prompt` provides. – CBroe Feb 28 '23 at 11:34
  • @MCodet JS uses "lexical scoping", meaning that what a function can access is determined based on where the function is defined (notice how there is no `playerSelection` variable defined in the code outside of the `function getComputerChoice() {` definition or within the function itself. Instead, you seem to think that JS uses "dynamic scoping", where the location of the function call would determine what `getComputerChoice` has access to, but JS doesn't do that. This answer on [lexical vs dynamic scoping](https://stackoverflow.com/a/22395580/5648954) might clarify a few things about scope. – Nick Parsons Feb 28 '23 at 11:37
  • You might also find this answer useful to understand how scoping works: [What is the scope of variables in JavaScript?](https://stackoverflow.com/a/500459) but essentially you'll want to update your `playRound()` to accept parameters and then pass those through in `game` as mentioned. – Nick Parsons Feb 28 '23 at 11:41

2 Answers2

2

You could use an input radio instead, make it simpler for the user and reduce error margin.

Use querySelectorAll to get all of your radio elements then iterate thru them then addEventListener click to each of them. I got rid of the game funcion since I already added events to your input, the game will begin as soon as you pick an option.

Get the values of playerSelection and computerSelection then call playround(x,y) send both parameters and thats it

function getComputerChoice() {
  let computerChoice = Math.floor(Math.random() * 3);
  return computerChoice;
}

function playRound(playerSelection, computerSelection) {
  let result;
  switch (playerSelection) {
    case 1:
      if (computerSelection == 1) {
        result = 'Draw';
      } else if (computerSelection == 2) {
        result = 'You Lose! Paper beats Rock';
      } else {
        result = 'You Win! Rock beats Scissor';
      }
      break;
    case 2:
      if (computerSelection == 1) {
        result = 'You Win! Paper beats Rock';
      } else if (computerSelection == 2) {
        result = 'Draw';
      } else {
        result = 'You Lose! Scissor beats Paper';
      }
      break;
    case 3:
      if (computerSelection == 1) {
        result = 'You Lose! Rock beats Scissor';
      } else if (computerSelection == 2) {
        result = 'You Win! Scissor beats Paper';
      } else {
        result = 'Draw';
      }
      break;
  }
  return result;
}

let radios = document.querySelectorAll('input[type="radio"]');
radios.forEach((radio) => {
  radio.addEventListener("click", function() {
    const playerSelection = parseFloat(radio.value);
    const computerSelection = getComputerChoice();
    console.log(playRound(playerSelection, computerSelection));
  });
});
<fieldset>
  <legend>Select an option:</legend>

  <div>
    <input type="radio" id="rock" name="selection" value="1">
    <label for="rock">rock</label>
  </div>

  <div>
    <input type="radio" id="paper" name="selection" value="2">
    <label for="paper">paper</label>
  </div>

  <div>
    <input type="radio" id="scissor" name="selection" value="3">
    <label for="scissor">scissor</label>
  </div>
</fieldset>
Chris G
  • 1,598
  • 1
  • 6
  • 18
1

When those two values are evaluated, function playRound() will be invoked passing the playerSelection and computerSelection arguments into playRound().

This would have totally worked, however that has not been done in your product. Here is an example of something that would have worked (only inclusive of the playRound and game functions):

function playRound(playerSelection, computerSelection) {
  if (playerSelection === computerSelection) {
    return 'Draw!';
  } else if (playerSelection === 'rock' && computerSelection === 'scissor') {
    return 'You Win! Rock beats Scissor';
  } else if (playerSelection === 'rock' && computerSelection === 'paper') {
    return 'You Lose! Paper beats Rock';
  } else if (playerSelection === 'paper' && computerSelection === 'rock') {
    return 'You Win! Paper beats Rock';
  } else if (playerSelection === 'paper' && computerSelection === 'scissor') {
    return 'You Lose! Scissor beats Paper';
  } else if (playerSelection === 'scissor' && computerSelection === 'paper') {
    return 'You Win! Scissor beats Paper';
  } else if (playerSelection === 'scissor' && computerSelection === 'rock') {
    return 'You Lose! Rock beats Scissor';
  } return 'Invalid input';

}


function game() {
  const playerSelection = prompt("Choose hand signal", "");
  const computerSelection = getComputerChoice();
  console.log(computerSelection);

  playRound(playerSelection, computerSelection) 

}

As you can see, the only things that needed to be changed were the parameters within the function.

  • Thank you for pointing that out and clearing up the uncertainty! That makes sense. Why couldn't I figure that out. – M Codet Feb 28 '23 at 12:25