9/9 Next steps restarting on tie/wrong input


#1

Hello. I have recently started the JavaScript course in CodeAcademy and I'm loving it.

For this lesson, instead of the suggested "rope" selection, I have decided to add Lizard and Spock, as seen on a certain TV show many will be familiar with.

From what I can tell, it works as intended, which completes step 02.

Now for the steps 01 and 03 - handling what happens when there is an input other than rock, paper, scissors, lizard or spock and handling ties.

For both, I have decided that the game should restart, and ask for a new input.

Because I have read a dozen threads relating to the same issues, many of which were answered by suggesting the use of knowledge from later lessons ("while" loops and such), I wanted to ask whether it is possible using only the functions that we have learned up until now. The reason I don't want to use the later functions is to complete my learning of the current ones and have less problems with them later on.

I am thinking about maybe making a function that checks the output, and if any of the two error messages are returned (wrong input/tie), the game restarts. But I have been unable to successfully make such a function.

I will paste the code that I have written up until now:

//1. User choice
var userChoice=prompt ("Rock, Paper, Scissors, Lizard or Spock?");
console.log("Player chooses: "+userChoice);

//2. Computer choice determined by random numbers divided into intervals. 5 choices total.

var computerChoice=Math.random();
if (computerChoice<=0.20){
    computerChoice="Rock";
}
else if (computerChoice>0.20,computerChoice<=0.40){
    computerChoice="Paper";
}
else if (computerChoice>0.40,computerChoice<=0.60){
    computerChoice="Scissors";
}
else if (computerChoice>0.60,computerChoice<=0.80){
    computerChoice="Lizard";
}
else {
    computerChoice="Spock";
}
console.log("Computer chooses: "+computerChoice);

/*3. This section defines the winner by comparing choices.
Rock beats Scissors and Lizard, loses to Paper and Spock.
Scissors beats Paper and Lizard, loses to Rock and Spock.
Paper beats Rock and Spock, loses to Scissors and Lizard.
Lizard beats Paper and Spock, loses to Rock and Scissors.
Spock beats Rock and Scissors, loses to Paper and Lizard.
*/
var compare=function(choice1,choice2){
    if (choice1===choice2){
    console.log("The result is a tie! Please choose again!");
    }
    else if (choice1==="Rock"){
        if (choice2==="Scissors"){
            return "Rock wins!";
        }
        else if (choice2==="Paper"){
            return "Paper wins!";
        }
        else if (choice2==="Lizard"){f
            return "Rock wins!";
        }
        else {
            return "Spock wins!";
        }
    }
    else if (choice1==="Scissors"){
        if (choice2==="Rock"){
            return "Rock wins!";
        }
        else if (choice2==="Paper"){
            return "Scissors wins!";
        }
        else if (choice2==="Lizard"){
            return "Scissors wins!";
        }
        else {
            return "Spock wins!";
        }
    }
    else if (choice1==="Paper"){
        if (choice2==="Rock"){
            return "Paper wins!";
        }
        else if (choice2==="Scissors"){
            return "Scissors wins!";
        }
        else if (choice2==="Lizard"){
            return "Lizard wins!";
        }
        else {
            return "Paper wins!";
        }
    }
    else if (choice1==="Lizard"){
        if (choice2==="Rock"){
            return "Rock wins!";
        }
        else if (choice2==="Scissors"){
            return "Scissors wins!";
        }
        else if (choice2==="Paper"){
            return "Lizard wins!";
        }
        else {
            return "Lizard wins!";
        }
    }
    else if (choice1==="Spock"){
        if (choice2==="Rock"){
            return "Spock wins!";
        }
        else if (choice2==="Scissors"){
            return "Spock wins!";
        }
        else if (choice2==="Paper"){
            return "Paper wins!";
        }
        else {
            return "Lizard wins!";
        }
    }
else {
    console.log ("Invalid input. Choose again.");
    }
}
console.log(compare(userChoice,computerChoice));

Edit: I forgot to mention, whenever there is a tie, I get an "undefined" printout to the console. Why exactly is this happening? I don't think I left undefined variables.
Example (tie happened by running the code above, this is the console message):

Player chooses: Rock
Computer chooses: Rock
The result is a tie! Please choose again!
undefined


#2

@verrrtigo,

As you are calling the compare function with
console.log( compare....)
you will end with a console.log() within a console.log() when you have a tie...
Change the console.log() within your compare function in a return Statement.


#3

@verrrtigo,

1 To extend the userChoice-prompting with a validity-check, you would
embed the prompting into a function-body...
So you would start by
var getUserChoice = function() { your prompting here };

2 If you are extending the choice-possibillity, you have to extend the
so-called truth-table.

Your new Decisions-Table: fill-in ?? wins...

              | ch-2  |  ch-2  | ch-2     | ch-2   |
              | rock  |  paper | scissors | rope   |
  ------------|-------|--------|----------|--------|
              |       | paper  |  rock    | ????   |
 choice1  rock|   X   | wins   |  wins    |  wins  | (1st else if )
              |       |        |          |        |
  ------------|-------|--------|----------|--------|
              | paper |        |scissors  |  ? ?   |
 choice1 paper| wins  |    X   |  wins    |  wins  | (2nd else if )
              |       |        |          |        |
  ------------|-------|--------|----------|--------|
              |  rock |scissors|          |  ?  ?  | 
 ch-1 scissors|  wins | wins   |   X      |  wins  | (3rd else if )
              |       |        |          |        |
  ------------|-------|--------|----------|--------|
              |  ? ?  | ? ? ?  |  ? ? ?   |        | 
 ch-1 rope    |  wins | wins   |   wins   |    X   | (4th else if )
              |       |        |          |        |
  ------------|-------|--------|----------|--------|

3 What you want is a loop-construct...
create the getUserChoice function using return-statement
create the getComputerChoice function using return-statement
creat the compare function using return-statement

As you are using return-statements you call the compare-function
var theResult = compare(userChoice,computerChoice);
and thus having the =result= of the game in the theResult variable

===========================================

var playTheGame =function() {
    var playAgain =true;
    var userChoice="";
    var computerChoice="";
    var theResult="";

   while (playAgain) {

       //execute the pre-declared getUserChoice-function
       var userChoice = getUserChoice();
       console.log("User choice is " + userChoice);

        //execute the pre-declared getComputerChoice-function
        var computerChoice = getComputerChoice();
        console.log("Computer choice is " + computerChoice);

        //execute the compare-function and capture the-result
        theResult = compare(userChoice,computerChoice);
        console.log("The result is " + theResult);

    if (theResult === "It is a tie!") {
       playAgain = true;
    } else {
      playAgain = false;
    }

    //end of -while- loop is reached, and if VALUE of playAgain === true
    // the loop will start over
    } //closing the while-loop
 }; //closing the function-body of playTheGame

// call the function playTheGame
playTheGame();

#4

Ok i might have kind of solved the 'game restarts' problem without using any loops after much tries, but this comparison between rock, paper and scissors is a bit confusing to be honest. I am pasting my code below which of course has errors and hence will be very kind if any of you can modify it without using the loops. Also problem 1 of an invalid error is solved here, but problem 2 is not solved. My target mainly was problem 3.

var userChoice = prompt("Do you choose rock, paper or scissors?");
var restartChoice = userChoice;
var computerChoice = Math.random();
if (computerChoice < 0.34) {
    computerChoice = "rock";
} else if(computerChoice <= 0.67) {
    computerChoice = "paper";
} else {
    computerChoice = "scissors";
} 

console.log("Computer: " + computerChoice);
var compare = function(choice1, choice2) {
    if (choice1 === choice2) {
        restartChoice = prompt("The result was a tie, please select among rock, paper or scissors again");
        
    }
    
    else if (choice1 === "rock") {
        if (choice2 === "scissors") {
            return "rock wins"
        } else {
            return "paper wins"
        }
    }

    else if(choice1 === "paper") {
        if(choice2 === "rock") {
            return "paper wins"
            
        } else {
            return "rock wins"
    }
    }

    else if(choice1 === "scissors") {
        if(choice2 === "rock"){
            return "rock wins"
        } else {
            return "scissors wins"
        }
            
        }
        else if(choice1 || choice2 !== computerChoice) {
            alert("not a value")
        }
        
       
    }

compare(userChoice, computerChoice);
compare(restartChoice, computerChoice);

#5

@gablusky,
If you want to experiment....

nice to know

You could test in labs.codecademy.com
choose Javascript
You will get a split-screen
In the left-hand-side you paste-in your code
click on the Run button.
The right-hand-side is the console

references

www.crockford.com --> for most respected guide-line in Javascript
like coding convention
www.crockford.com
http://javascript.crockford.com/code.html
http://javascript.crockford.com/survey.html

==============================

But i would not change the functionality of the compare function.
Furthermore, as you are using a return-statement
giving you a result, with _NO-display

Please read
http://www.codecademy.com/forum_questions/559dcb4be39efe550f00006b
and concentrate on:

  • the execution of the compare function (keeping in mind that the return statement is used )

#6

Thank you.

I didn't see it at first, but now that you've mentioned it, it's crystal clear. Hindsight is 20/20, as they say :smile:


#7

I have tested this code a little bit. What I have noticed is that if there is a tie, (e.g. both the player ant the computer choose rock), you get a prompt for new input. So the player input changes, but the computer choice stays the same, thus allowing you to cheat.

For example: you pick rock, computer also picks rock. There is a tie. You pick paper, computer's choice stays the same as before (because only the user's choice is updated). You win.

I know in theory what needs to be done, but due to my lack of knowledge and experience with programming I only have a slight idea of how to translate it into code. A slight idea is better than none, I will try to play around a little and make it work. That is one of the ways how learning works, after all :smile:


#8

Okay, after tinkering around a little and adapting parts of the code @gablusky posted, I have made the "incorrect input" part work somewhat. As in, it only works once. To make it work further, it seems that I have to add new textwalls and call functions again manually. I suppose this is where loops come in.
I think I will push this aside for a little while and come back later when I've learned more. The answers in this thread gave me useful information and somewhat improved my command over the functions. Thank you.

One last question. So as not to create a new thread, I will ask it here.
I have re-viewed my computer choice part using CodeAcademy Labs and decided to edit it because Labs shows exclamation marks next to them, indicating some sort of slight error (code runs though).

Currently the relevant code excerpt is as follows:

var repeatComputerChoice=function(){
var computerChoice=Math.random();
if (computerChoice<=0.20){
computerChoice="Rock";
}
else if (computerChoice>0.20,computerChoice<=0.40){
computerChoice="Paper";
}
else if (computerChoice>0.40,computerChoice<=0.60){
computerChoice="Scissors";

And so on. What I wanted to ask is: for example, describing when Paper is chosen, does the IF function take into account the previously stated interval of computerChoice<=0.20 for Rock, thus making my addition computerChoice>0.20 in the next step slightly obsolete? I have removed the parts in Bold from the code and tried running it again and it seemed to still work properly.

This is the error message I was shown.


#9

@verrrtigo,

-1

+++++ if else-if else skeleton ++++++++++
The Math.random() method will deliver a number with a value
in the range of 0_(included)_ upontill 0.9999_(1 excluded)_.

As you will have to divide the number range form 0_(inclusive)_ to 0,9999_(so 1 excluded)_
into 3 equal partitions
we have to use an if else-if else statement.
The if else-if else skeleton looks like:

    if (conditionA) {
               //conditionA is true
                //your code 
     } else if (conditionB) {
               //conditionA is false
               //conditionB is true
              //your code 
    } else {     // <=== !! Takes NO condition-statements !!
               //conditionA is false
               //conditionB is false
              //your code 
    }

following the Instructions the conditions would be:
1. If computerChoice is between 0 and 0.33, make computerChoice equal to "rock".
( 0 <= computerChoice && computerChoice <= 0.33) which we capture at the IF using
( computerChoice <= 0.33)

  1. If computerChoice is between 0.34 and 0.66, make computerChoice equal to "paper".
    ( 0.33 < computerChoice && computerChoice < 0.67) which we capture at the ELSE IF as
    ( computerChoice < 0.67 )

  2. If computerChoice is between 0.67 and 1, make computerChoice equal to "scissors".
    ( 0.67 <= computerChoice && computerChoice < 1) , you reached the ELSE level
    you can asume that computerChoice is greater equal to 0.67,
    the ELSE does NOT take a condition, just write your code.

=================================

In line 13 you should have used a logical operator instead of your comma-,
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators