Js 9 next steps, undefined after a tie


#1

I tried to complete the next steps just by using the skills presented until lesson 9. I only get an undefined error after a tie. I have included a console.log of computer's choice just to easily match the tie. Here is my code:

confirm("Click OK to play");

var computerChoice = Math.random();

var checkComputer = function (computer){
if (computer < 0.34)
{
computerChoice = "rock";
console.log("Computer: " + computerChoice);
}

else if(computer <= 0.67) 
{
	computerChoice = "paper";
	console.log("Computer: " + computerChoice);
} 
else 
{
	computerChoice = "scissors";
	console.log("Computer: " + computerChoice);
}

};
checkComputer(computerChoice);

var userChoice = prompt("Do you choose rock, paper or scissors?");

var compare = function (choice1, choice2) {
if (choice1 === choice2)
{
console.log("The result is a tie, play for the win!");
computerChoice = Math.random();
checkComputer(computerChoice);
userChoice = prompt("Do you choose rock, paper or scissors?");
checkUser(userChoice);
compare(userChoice, computerChoice);
}
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 "scissors wins";
}
}
else
{
if (choice2 === "rock")
{
return "rock wins";
}
else
{
return "scissors wins";
}
}

};

var checkUser = function (user){

if (user === "rock")
{
    console.log(compare(userChoice, computerChoice));    
}
else if (user === "paper")
{
    console.log(compare(userChoice, computerChoice));    
}
else if (user === "scissors")
{
    console.log(compare(userChoice, computerChoice));    
}
else
{
    userChoice = prompt("Do you choose rock, paper or scissors?");
    checkUser(userChoice);    
}

};
checkUser(userChoice);

console.log("User: " + userChoice);
console.log("Computer: " + computerChoice);


And here is the output:

Computer: scissors
The result is a tie, play for the win!
Computer: scissors
The result is a tie, play for the win!
Computer: paper
paper wins
undefined
undefined
User: rock
Computer: paper

Can you please point me to my error? Thanks in advance.


#2

Not sure if this will help or not, but why are you logging the compare function, which also includes logging information as part of its function? And since checkUser calls compare, isn't the last line here:

console.log("The result is a tie, play for the win!");
computerChoice = Math.random();
checkComputer(computerChoice);
userChoice = prompt("Do you choose rock, paper or scissors?");
checkUser(userChoice);
compare(userChoice, computerChoice);

actually redundant?

Admittedly, I'm not sure where exactly the undefined is being generated, but I would start there. The simpler the code, the fewer opportunities for error. Maybe someone else around here with more experience than me can help more?


#3

As @tagplayer25484 mentioned. Simpler is better.

It's best to not stray off the lesson path and only do what it's telling you to do. Being proactive in this case is actually a major downfall.

Also, Indention is a HUGE factor in others being able to read your code.

if (this===that)
{
console.log("blahblah")
userChoice= prompt("blahblah");
}

vs.

if (this===that) {
    console.log("blahblah")
    userChoice= prompt("blahblah");
}

#4

Thanks for the hints. The code was much more simpler but in order to solve the issue with the undefined output I implemented the compare functions and everything got quite messy..
Thanks to your feedback I realized the console.log in the confirm function does not make sense at all.

I guess I will continue with the course and try to refine my code as soon as I am ready.

As for the indention - my code looks different in the script.js. I don't know why it didn't paste properly here.

Once again thanks for the comments!


#5

About the undefined problem. What happens if the result is a tie?

If the result is a tie you end up here:

if (choice1 === choice2)
    {
        console.log("The result is a tie, play for the win!");
        computerChoice = Math.random();
        checkComputer(computerChoice);
        userChoice = prompt("Do you choose rock, paper or scissors?");
        checkUser(userChoice);
        compare(userChoice, computerChoice);
    }

What happens here is that you do some stuff and log some stuff and in the end run another instance of the compare function. But with running this new compare function this instance of the compare function isn't over. After you finally got a result returnned you'll come back to this specific function where you first got the tie and finish it. Finish it? Yes, ok there is nothing else to do as none of the other cases fits anymore, but still you need to finish it so it goes on until it reaches the very end and there it returns. And if you don't provide a return the interpreter will auto set a return; which has a value of undefined and that is the undefined that you see. Namely because you print that undefined via the console.log in your checkUser function. I hope this is not half as confusing as i think it is :smile:


#6

It was not confusing at all. Thanks for the detailed explanation.
I wanted to make sure the Computer chooses a new value in case the result is a tie and also check if user's input is valid. I did not consider the first time the compare function is called and resolves to tie, I am not completing the function but calling it again and in the end it returns back to completing the first call that returns undefined.
I know now where my mistake was and what I need to consider in the future - calling the same function while already executing it will at some point bring you back to the point where you left the first call. Hard to explain but I got it.. :wink:


#7

Wow, yes that is what I tried to explain :smile:One solution might be to return the compare e.g.

 if (choice1 === choice2)
    {
        console.log("The result is a tie, play for the win!");
        computerChoice = Math.random();
        checkComputer(computerChoice);
        userChoice = prompt("Do you choose rock, paper or scissors?");
        checkUser(userChoice);
        return compare(userChoice, computerChoice);
    }

thereby one instance throws it to the next and so on until it arrives at the console.log. Another solution would of course be to let the compare function be what it is after the exercise and just use its value e.g.

var result = compare(...,...);
console.log(result);
if(result === "the result is a tie!){
    do fancy repeating stuff;
}

Also if you go on and learn about loops the repetition will get a lot easier than using what is called recursion: "Looping by calling a function inside itself".


#8

Yeah, my mistake looks funny after understanding it :smile:
I searched for an answer before posting and since I am keeping on with the course, now I see why other people used while.