All right, guys, so now that we've loaded up all the knowledge that we need into our brains, it's
time to tackle the final project of the day.
And as I showed you in the beginning of the day, it's a Rock Paper Scissors game that we can play
with the computer.
So the game starts out by asking you to type 0 for rock, 1 for paper, or 2 for scissors.
So let's go ahead and type two for scissors, and then it's going to show you a graphic of your choice scissors,
and then the choice the computer made, which is rock. And of course, rock beats scissors
so you lose.
What this game boils down to is some way of randomly making a choice between rock, paper, or scissors
and then comparing that choice that the computer randomly generated against your choice.
And then based on the rules of rock, paper, and scissors, determining whether if you won, you lost or
whether if you had a draw.
While I was looking around, I actually came across the world rock paper scissors association.
And they have the official rules of the state of Rock Paper Scissors.
If you're not familiar with this game, it might be worth checking out this website.
Here are the three shapes of rock, paper, scissors.
And then the rules are that rock wins against scissors, scissors wins against paper, and paper wins
against rock.
Having all of this in mind, head over to replit/@appbrewery/ rock-paper-scissors-start
and go ahead and just fork the starting project.
Now you'll notice that in the starting project, I've already got the ASCII art for rock, paper and scissors
in here and they're each saved to a variable.
So what that means is that you can start out by just having a go at printing out let's say a rock.
And remember that these are variable names.
They're not strings, so they don't need the double quotes around them.
So let's run that.
And you can see what we get printed is the particular ASCII art that I chose in my print statement.
So this is already yours.
But as you'll notice, there's no other logic that I've provided you and you are going to rely on what
you learned in the previous days and most importantly, what you've learned in today's lessons to be
able to complete this challenge.
And it's worth comparing the outcome against the game of Rock Paper Scissors that I'll link to.
There's a couple of things to think about, namely, how are you going to decide who won or who lost?
How are you going to get the computer to choose a random shape, rock, paper, scissors, and how you
actually get this game to work in the same way that is demoed in this final version?
I'm going to go quiet now and I'm going to let you pause the video.
And I want you to spend at least ten or fifteen minutes working on this.
And if you get stuck, just try some things out or maybe watch some of the previous videos in the day
and just try to give it your best
go, and do a lot of struggling.
Hopefully you're going to succeed.
And once you're done, head back over here and I'll go through the solution with you.
So pause the video now.
All right, so we know that we've got all of this ASCII art, but for the moment, I'm just going to
start off by putting down the basic logic of this game.
And it's really helpful for you as well if you start thinking about breaking down the larger problem,
which is making the Rock Paper Scissors game into smaller problems that you can solve, like generating
a random number between one and three.
So we have some sort of proxy for Rock Paper Scissors. And then maybe thinking about putting down
the logic, well, if the computer chose scissors and I chose paper, then I'm going to lose.
Or if the computer chose rock and I chose paper, then I'm going to win.
And putting that down on a flowchart using draw.io or something like that can make this challenge a lot
easier as well.
But without further ado, the first thing I need to do is to produce a user choice.
Now, this is going to be the one that the user chose when they typed in a value.
And in order to get the value from them, I'm going to need to use a input.
And inside the input, I'm going to put the following prompt asking the user, what do you choose?
Type 0 for rock, 1 for paper or 2 for scissors.
Now, once I get hold of this input, hopefully, if the user is following my instructions, they're going
to type some sort of number, either zero or one or two.
Now that I've gotten hold of what the user wants to choose, the next thing to do is figure out what
the computer is going to choose.
So I'm going to make another variable called computer_choice and I'm going to generate a random number.
So to do that, remember, we have to import the random module.
And then we can start using it to generate random whole numbers by using random.randint.
And then the range is going to be between zero and two, because this is what I asked the user to do.
Type 0 for rock, 1 for paper, 2 for scissors.
So the computer is also going to choose between 0, 1 or 2.
Now that I've got the computer_choice, I'm actually going to just print it out for now instead of printing
out the actual shape, I'm just going to print out the number.
So computer chose and then let's go ahead and add a fstring.
And of course, that requires the F in front of the string.
So now if we just play the game as it is, remember that testing up while you're developing it is really,
really good practice.
It picks up on the bugs that you make along the way instead of waiting until the end when you've done
everything
and then it doesn't work and you have to untangle all of the lines of code.
At this point, I've already realized that it's actually not so great getting the user to type on this
line.
What I would much rather is to start a new line for them to type their answer on.
So if I run the code again, then it should look a bit like this.
My prompt is now here. So I'm going to choose 0 for Rock.
And then it tells me that computer also chose zero.
So in this case, this would be a draw.
But if I played this game again, you can see that the computer is probably going to choose something
different.
So I chose rock again
the computer chose 1, which is paper.
So now we can start thinking about how do we compare these two choices and how can we define the logic
of Rock Paper Scissors?
So I know that paper beats rock, scissors beats paper and rock will beat scissors.
So if zero is rock, one is paper and two is scissors, then two beats one and one beats zero.
So that's very simple for us to check in terms of using if statements,
right?
We could simply just check
well, if the computer choice is greater than the user choice, well then this probably means that the
computer wins.
But this is not true in all cases, right? Because if the computer chose 2 for scissors and the user
chose 0 for rock, then the user should win rather than the computer winning.
So we actually have some exceptions to this rule.
How can we catch the exceptions before we go down to this level of generalization?
Well, we could instead of using this as an if, we use this as an elif and we create another if statement
which says, well, if the user_choice is equal to zero, so if the user chose rock and the computer_choice
was 2, well then this means that in this case, the user actually wins.
Now, if we're thinking from the perspective of the user when they're playing this game, then they
don't really care if the computer won or the user won. They want to know, did they win or did they lose?
So let's change this wording a little bit.
We'll say, instead of user wins, we'll say you win.
And if the computer wins, then we'll say you lose.
So now if we run our program and test it out, so let's say I'm going to type 0 for rock and the
computer chooses 2, but we actually get an error.
It tells us that the greater than comparison is not supported between instances of int and string.
What's going on here?
Well, remember that we get our inputs as a number, but the input is always going to be a string.
So if we want this to be a number,
then we're going to have to wrap it inside an int.
So now we turn it into a whole number.
Now, this might be a good point to address
well, what should happen if they typed something that wasn't 0, 1 or 2, whether they typed 34?
Well, then naturally they should probably lose,
right?
So we can add an else statement addressing this situation. So we could say else we just print
You typed an invalid number.
You lose. Cool.
So that sorts that out.
Now let's run our code again and see if it works.
What do you choose?
Type 0 for Rock.
I'm going to choose rock again.
Computer chose zero and it tells me that you typed an invalid number.
Well, actually, zero is not an invalid number.
So what's going on here?
Well, it's because it didn't fit this criteria.
So I had zero,
computer had zero, and it didn't fit this criterion because zero is not greater than zero.
So it basically defaulted to the final else statement.
But what's actually happening here is that that was a draw.
Computer chose rock,
I chose rock.
That's a draw in the official rules of Rock Paper Scissors.
So how do I catch that?
Well, I could create another elif statement which says, well, if the computer_choice is equal to
the user_choice, well, then we're going to print
it's a draw.
Now, let's test our app again and see if there are any other situations where our code is not behaving
properly.
I'm going to choose rock again, computer chose rock as well.
And I guess it's a draw, so that's pretty good.
Now, if I choose 0 and the computer chose 2, then this is going to be the statement that gets
triggered and I win.
So that's pretty good.
Now, what if I chose 2 for scissors and the computer chose 0?
Well, in this case, rock beats scissors
so it should actually say I lose.
But instead it says you typed an invalid number.
So it defaulted to the else statement again because this particular situation is not caught by any of
these statements.
So what do we have to do instead?
Well, we actually need another elif to say, well, if the computer_choice was equal to 0 and
the user_choice was equal to 2, well, this means that rock beats scissors
so I lose and the computer wins.
Now, the final one that we need to catch is this case.
If I type 1 for paper and computer chooses 0 for rock, it again defaults to the else statements
whereas in fact in this case it should tell me that I won.
So what's missing here?
Well, it's the partner to this particular statement.
If computer_choice is greater than user_choice then I lose.
But on the other hand, if the user_choice was greater than the computer_choice, then I actually should
win.
So now the final thing we might have to fix is this else statement now actually never gets called because
this is what happens.
So let's say that I choose 456.
It tells me that computer chose 2, I win.
What's happening here?
Well, it's actually this particular line that's being carried out.
user_choice is greater than computer_choice.
This is not what we want.
We want it to default to
You typed an invalid number.
You lose. So we can actually just use else in this situation.
We actually need to provide a condition.
We're going to use elif to check if the user_choice is greater or equal to three,
now, the computer will never choose anything other than 0, 1 and 2
so we don't have to check that one.
But the user could choose something above 3 or below 0.
So we can use an or statement to catch this. Or if the user_choice is less than zero,
well, in this case, you typed an invalid number, you lose.
But that's not all that we have to do.
If we hit run and we again type some extraordinarily large number, you'll see that it still says
computer chose 1.
You win.
What's going on?
We have this statement that should catch this situation, but it's right at the bottom.
So it's not going to be checked until one of the previous ones are checked.
Namely, it's one of these that's going to be the problem.
So what we have to do is we have to move this statement above all the lines so that we first check if
the user_choice is greater than three or less than zero.
And if that's not true, do we actually continue checking to see who won the game.
Now, finally, we can run our code type an invalid number and get you typed an invalid number. You lose.
So now that we've actually got our logic all sorted out, the next step is to include our images.
And to do that, we have to somehow match it up with these numbers we have,
right? 0, 1 and 2.
Now, there's many, many ways that you could do this and you could solve this project.
But the easiest way is probably putting the game images into a list where we have rock as the first
one, paper as the second one and scissors as the last one.
So we're using the fact that lists have a order that is always going to be followed. So we can now get
hold of the rock picture by getting game_images[0].
We can get scissors by doing game_images[2] and so on and so forth. And we can match those up to our
choices, the user_choice and the computer_choice.
So when the user chooses a number, then we're going to print from the game_images and we're going to
use our little square brackets to select the image we want from this list.
And the one that we want is going to be based on the user's choice, right?
0 for rock, 1 for paper, 2 for scissors.
So we're going to put user_choice as the index to pick out an image from game_images. Now down here for
the computer_choice, instead of printing the number that the computer chose, I'm going to delete that
and add a little colon.
So that way it's going to show computer chose
and then I'm going to print the image of the choice that the computer made.
So I'm going to add another print statement,
I'm going to tap into the game_images and then inside some square brackets, I'm going to use the computer
choice which is going to be between 0, 1 and 2 as the index to pick out the corresponding image
from my list game_images.
So now we're finally ready to run our code and I'm going to choose 0 for rock and the computer chose
paper.
So paper beats rock, I lose.
Let's try this again.
I'm going to choose scissors and computer chose scissors.
It's a draw. But we have also introduced a bug.
So if we test this using a number that's outside of this range, 0, 1 or 2,
so let's try 5. And we hit enter,
what do we get?
We get a index error.
So what has happened here?
Well, this is up to you to debug.
Well, this is a really good opportunity for you to practice your debugging.
So think about what has
changed since the last time we tested this and how you can fix the code so that it works as expected,
so telling us that you typed an invalid number, you lose whenever we type a number that's above or
equal to three or less than zero.
So I want you to pause the video and see if you can debug this challenge so that when you type in 5,
you get this printed. Pause video now.
All right, so what's going on here, because we tested this and it worked, but in between that time,
we also added this line because we wanted to get a hold of the game images based on the user's choice.
Now, at this point, the user's choice is unchecked by the if statement.
So it could still be equal to 4 or 5 or 10 or a million.
So if in that case, it tries to get hold of the fifth image from the game_images list, well, it doesn't
exist.
There's only 0, 1 and 2.
So to fix this, we need to move this if statement so that it gets checked before this line of code
gets carried out.
So let's go ahead and cut this line of code out and put it right above this print statement.
So in this case, if the user types in a choice that's above or equal to three or less than zero,
we're going to print this.
But else, if they typed in any other number, then we want the rest of the code to continue.
So let's select the rest of the code, hit tab and tab it over
so that is included under the else statement.
Now let's go ahead and change this from elif just to an if because we're no longer checking it as another
else-
if statement. It is just a straight up
if. So, in this case, if they typed a 5, then it will go into this basket and it will finish there.
But otherwise, it will go into this basket and it will continue checking later on.
So did you manage to debug your code and figure out the issue?
This is one of the most important skills
as a programmer. You have plenty of opportunities coming up to practice your debugging.
And if you ever want more practice, head over into the Q&A and see what other students have issues
with and see if you can help them out by practicing your debugging skills.
Now, we have completed the project by using everything from lists to randomization to variables to
if statements and a whole lot of logic.
So how did you get on with this project? If you struggle
this is the time again to go back to it and maybe map things out using a flow diagram or try to run
the code using Thonny to see how it does it step by step.
But the important thing is that you got to write your own code and you got to make it work.
And this is the only way that you'll understand what's going on so that you can continue on.
And as things get harder, you'll be able to learn more because you've already understood all of the
previous knowledge.
So I hope you had fun with me today
learning and building, and hopefully I will see you tomorrow bright and early.
So that's good night from me for today.