9. R.P.S. Getting undefined and don't know why


#1


https://www.codecademy.com/courses/javascript-beginner-en-Bthev-mskY8/1/5?curriculum_id=506324b3a7dffd00020bf661


I have completed all three bonus exercises. The code works except for one thing. I keep getting "undefined" returned into the console. I know "undefined" means that I have a variable I haven't given a value. I can't find where it is and need help snooping it out. It only occurs when a tie happens and the function is called again. I have a gut feeling that the same function being called multiple times is causing the problem, but, I need help with a fix.


var compare = function(choice1, choice2) {
     
    if (choice1 === choice2)  {
        console.log("tie");
        tie();
       
    }
       
    
    else if (choice1 === "rope") {
        if (choice2 === "paper") {
           console.log("tie");
            tie();
            
        }

        
        else if (choice2 === "rock") {
            return "rope wins";    
        }
        else{
            return "scissors win";    
        }
    }
    
    
    else if (choice1 === "rock") {
        if (choice2 === "scissors") {
            return "rock wins";
        }
        else if (choice2 === "rope") {
            return "rope wins";    
        }
        else {
            return "paper wins";    
        }
    }
    
    else if (choice1 === "paper") {
        if (choice2 === "rope") {
            console.log("tie");
            tie();
            
            
        }
   
        
        else if (choice2 === "rock") {
            return "paper wins";
        }
        else {
            return "scissors wins";    
        }
    }
    
    else if (choice1 === "scissors") {
        if (choice2 === "rock") {
            return "rock wins";
        }
        else{
            return "scissors wins";    
        }
    }
    
        
    else {
        return userChoice +" " +"is not a known weapon.  Please select an appropriate weapon from the following list: rock, paper, rope, or scissors.";    
    }
    
    
}

var tie = function() {
    userChoice = prompt("Do you choose rock, paper, rope or scissors?");
    
    computerChoice = Math.random();
    
    if (computerChoice < 0.25) {
	    computerChoice = "rock";
    } 
    else if(computerChoice <= 0.5) {
	    computerChoice = "paper";
    } 
    else if (computerChoice <= .75) {
	    computerChoice = "scissors";
    } 
    else {
        computerChoice = "rope";    
    } 
    
    console.log("Computer chooses:" + " " + computerChoice);
    console.log("Player chooses:" + " " + userChoice);
    console.log(compare(userChoice, computerChoice));
};

tie();


#2

if you want to call a function before you defined it, use the function declaration:

function tie(){}

or simply move the function call (line 1, tie()) after the function, see here


#3

Aren't functions hoisted in Javascript? I was under the impression that where the function is written doesn't matter since all functions in the code are put into memory before any code is ran? Am I wrong?


#4

if you use function declaration yes, but if you use Function Expression (like you did) the function is loaded when the line is reached. You should have gotten this from the stackoverflow question i linked to?


#5

I did read the stackoverflow question you linked and thanks for that, a lot of good stuff there even beyond what I'm doing here. However, I rewrote the code so the function call was after the function and the code behaved exactly the same as it had before. I don't think the problem lies with the functions themselves. The "undefined" keyword being returned in the console makes me think I have an undeclared variable somewhere. I'm gonna dig around some more and see if I can solve it.


#6

i don't see a modified code? Maybe if you post an updated version i can have a look?


#7

The main post is updated. Just to be clear. The code does everything it's supposed to with one exception, when the console prints out the results, the bottom line always says undefined and I'm curious how to eliminate it.


#8

this should fix it:

var compare = function(choice1, choice2) {
     
    if (choice1 === choice2)  {
        console.log("tie");
        return tie();
       
    }
       
    
    else if (choice1 === "rope") {
        if (choice2 === "paper") {
           console.log("tie");
            return tie();
            
        }

        
        else if (choice2 === "rock") {
            return "rope wins";    
        }
        else{
            return "scissors win";    
        }
    }
    
    
    else if (choice1 === "rock") {
        if (choice2 === "scissors") {
            return "rock wins";
        }
        else if (choice2 === "rope") {
            return "rope wins";    
        }
        else {
            return "paper wins";    
        }
    }
    
    else if (choice1 === "paper") {
        if (choice2 === "rope") {
            console.log("tie");
            return tie();
            
            
        }
   
        
        else if (choice2 === "rock") {
            return "paper wins";
        }
        else {
            return "scissors wins";    
        }
    }
    
    else if (choice1 === "scissors") {
        if (choice2 === "rock") {
            return "rock wins";
        }
        else{
            return "scissors wins";    
        }
    }
    
        
    else {
        return userChoice +" " +"is not a known weapon.  Please select an appropriate weapon from the following list: rock, paper, rope, or scissors.";    
    }
    
    
}

var tie = function() {
    userChoice = prompt("Do you choose rock, paper, rope or scissors?");
    
    computerChoice = Math.random();
    
    if (computerChoice < 0.25) {
        computerChoice = "rock";
    } 
    else if(computerChoice <= 0.5) {
        computerChoice = "paper";
    } 
    else if (computerChoice <= .75) {
        computerChoice = "scissors";
    } 
    else {
        computerChoice = "rope";    
    } 
    
    console.log("Computer chooses:" + " " + computerChoice);
    console.log("Player chooses:" + " " + userChoice);
    return compare(userChoice, computerChoice);
};

console.log(tie());

in short, when you call tie() again in case of a tie, the result of compare isn't returned, causing the undefined. You have to return everything when using recursive function calls to prevents undefined s. I know, horrible explanation.


#9

Your explanation actually makes a lot of sense now that I'm aware of the interaction. I see where undefined was coming from and why. Thank you a lot for your help. Learned a lot here!


#10