Netz
Netz

Reputation: 31

JavaScript - rock, paper, scissors - user input is not acknowledged

i recently started learning JavaScript and been working on the final assignment for the class where we have to create a "Rock, Paper, Scissors" game. While i did manage to solve the same type of a game at codecademy.com - it was mostly with the help of several If Statements and 1 function. However, for this assignment we're required to use functions, arrays and loops, while keeping a score of each player's progress, notifying the user of the updated scores, as well providing the chance to exit the game at any time... here's the detailed explanation of what's required for this assignment:

Write a Rock, Paper, Scissors game. Your task is to create the logic for a Rock, Paper Scissors game. The game will welcome a user and then prompt the user for their first round of play by asking them to type rock, paper or scissors Each round will have the following steps:

  1. The user will be prompted to type, rock, paper, scissors OR exit
  2. The computer will randomly pick either rock, paper or scissors and alert the user to this choice
  3. A winner will be declared and a point will be awarded to the winner.
  4. The user will be alerted of the running score for both themselves and the computer.
  5. The round will be repeated

You are to evaluate whether or not the user wins, loses or ties the round, based on the rules here: http://www.rinkworks.com/games/rps.shtml The game should have an infinite number of rounds, until the user types exit in the game prompt. If the user types the word exit into a prompt, let the user know who won the game and the final score. I will ultimately leave the architecture of the program up to you, but do require that: You will need to incorporate conditionals, loops, arrays and make use of function calls and comments to create this program. - the computer creates a new random choice between rock, paper and scissors by calling a function you create to return either “rock”,”paper”,”scissors” - the logic for determining a winner of a round is contained inside a function you design to take both the user and computer’s choice as parameters

I checked this in Chrome's console for errors and the problem that i'm having is that the code seems to work... only that it's the computer that's the only winner here... hence it seems as if the user input is completely ignored. Besides, if i hit the 'Cancel' button i get an error (according to Chrome's console) on line 20 telling me:

Cannot read property 'toLowerCase' of null

...I've originally added the following line of code for a reason, which is to make sure the user input matches all the lower-case options...

return userInput.toLowerCase();

When i removed the .toLowerCase() method only to simply return the userInput (and then ran the code in Chrome's console again), i got stuck in an infinite loop...

Here's my entire code:

var choice1Score = 1;
var choice2Score = 1;

function compChoice() {
	var choiceArr = ["rock", "paper", "scissors"]; 
	var random = choiceArr[Math.floor(Math.random() * 3)];
	return random;
}

function userChoice(){
	var userInput = prompt("Please enter your choice of either rock, paper or scissors. To exit, hit the 'Cancel' button.");
	return userInput.toLowerCase();
}


while (userChoice != "Cancel") {

    function scoring(choice1, choice2) {
        if (choice1 === choice2) {
            return "The result is a tie.";
        } if (choice1 === "rock") {
            if (choice1 === "scissors") {
                return "Rock wins. Your score is: " + choice1Score++;
            } else {
                return "Paper wins. The computer's score is: " + choice2Score++;
            }
        } if (choice1 === "paper") {
            if (choice1 === "rock") {
                return "Paper wins. Your score is: " + choice1Score++;
            } else {
                return "Scissors win. The computer's score is: " + choice2Score++;
            }
        } if (choice1 === "scissors") {
            if (choice1 === "paper") {
                return "Scissors win. Your score is: " + choice1Score++;
            } else {
                return "Rock wins. The computer's score is: " + choice2Score++;
            }
        }
    }
    alert(scoring(userChoice(), compChoice()));

}

Any help, suggestions and comments will be much appreciated!

Upvotes: 3

Views: 2565

Answers (5)

user13633609
user13633609

Reputation:

This is what I would do:

  values = {
  'Paper' : {
               'Paper'   : 'Ties with'
               'Rock'    : 'Beats'
               'Scissors': 'Loses to'
             }
  'Rock' :  {
               'Paper'   : 'Loses to'
               'Rock'    : 'Ties with'
               'Scissors': 'Beats'
             }
  'Scissors' : {
                 'Paper'   : 'Beats'
                 'Rock'    : 'Loses to'
                 'Scissors': 'Ties with'
                }
  }
  a = prompt("First sign?\n")
  b = prompt("Second sign?\n")
  console.log(a, values[a][b], b, "!")

How it works

> First sign?
> Paper      <-- This is input
> Second sign?
> Rock       <-- This is input
> Paper Beats Rock!

Upvotes: 0

Noble Mushtak
Noble Mushtak

Reputation: 1784

When you hit the "Cancel" button, prompt() returns null, so userInput is null, resulting in the error. Instead of checking if the user's choice equals "Cancel", check if userInput is null. If it is, stop the game.

Also, in scoring, you have three typos where you type choice1 for the computer's choice. Remember that the computer's choice is choice2 as you passed them in, not choice1.

Furthermore, don't put scoring() inside your while loop because then, scoring() is re-created over and over again each time the player plays the game. This is much less efficient than just creating it once by putting it on the outside.

var choice1Score = 1;
var choice2Score = 1;

function compChoice() {
	var choiceArr = ["rock", "paper", "scissors"]; 
	var random = choiceArr[Math.floor(Math.random() * 3)];
	return random;
}

function userChoice(){
	var userInput = prompt("Please enter your choice of either rock, paper or scissors. To exit, hit the 'Cancel' button.");
	//If userInput is null, return null:
	if (userInput == null) return null;
	//Otherwise, return the lowercase version of userInput:
	return userInput.toLowerCase();
}

function scoring(choice1, choice2) {
    if (choice1 === choice2) {
        return "The result is a tie.";
    } if (choice1 === "rock") {
        if (choice2 === "scissors") {
            return "Rock wins. Your score is: " + choice1Score++;
        } else {
            return "Paper wins. The computer's score is: " + choice2Score++;
        }
    } if (choice1 === "paper") {
        if (choice2 === "rock") {
            return "Paper wins. Your score is: " + choice1Score++;
        } else {
            return "Scissors win. The computer's score is: " + choice2Score++;
        }
    } if (choice1 === "scissors") {
        if (choice2 === "paper") {
            return "Scissors win. Your score is: " + choice1Score++;
        } else {
            return "Rock wins. The computer's score is: " + choice2Score++;
        }
    }
}

//Keep looping infinitely:
while (true) {
    //Get the user's choice:
    var curUserChoice = userChoice();
    //If the user's choice is clicking the "Cancel" button, exit:
    if (curUserChoice == null) break;
    //Otherwise, play the game and alert the user:
    alert(scoring(curUserChoice, compChoice()));
}

Upvotes: 1

Archyron
Archyron

Reputation: 56

Well, one of the issues here is you aren't comparing the two choices other than in the tie case. For example:

if (choice1 === "rock") {
    if (choice1 === "scissors") {
        return "Rock wins. Your score is: " + choice1Score++;
    } 
    else {
        return "Paper wins. The computer's score is: " + choice2Score++;
}

The second line should be if (choice2 === "scissors") {

Upvotes: 2

Manu Masson
Manu Masson

Reputation: 1737

First off, change this: while (userChoice != "Cancel")

To: while(userChoice != "cancel")

Upvotes: -4

John C
John C

Reputation: 501

Are you aware that your while loop is checking if "Cancel" not "cancel" is entered? If you take the lower case of "caNCel" it will never equal "Cancel". I also notice that userChoice, the variable, isn't set or defined anywhere. Assuming what you've provided is your entire code, you need to think through how to handle this (HINT: you should call userChoice() only once for each round; since you need to do multiple checks, did they enter cancel or who won, you'll need to store it to a variable first).

Also, I think you mean for the nested if statements to check against choice2.

Might I suggest you look into learning how to use the Chrome console to debug using breakpoints so that you can look at the value of variables at each instruction as Chrome executes the the program line by line? These are both issues you would have easily caught had you looked at the exact values Chrome was using.

Upvotes: 2

Related Questions