ZAMYLA CHAN: All right. Hello, everyone, and welcome to Walkthrough 0. My name's Zamyla, and I'll be leading these walkthroughs this year. In CS50, every problem set is accompanied by a walkthrough whereby we'll go through the week's problem set, talk it through, talk how to get started, discuss different techniques and tips to really break the problem set into some manageable bites. I'm also really happy to answer any questions that you have on the problem set. Without further ado, I'm glad you're here, whether you're here in person or tuning in online. Let's get started. So the first p-set in CS50-- actually, we're not going to get into typing and machine code stuff quite yet. We're actually going to be using Scratch, which is a program that allows us to do some drag and drop programming. And so even though we're not typing, it really allows us to explore some of the fundamental concepts that we'll use all throughout CS50. Now, some of these concepts are listed here in the Toolbox. What I'd like to do for every walkthrough is present you all with a set of tools that you can use for the walkthrough. And so, don't worry. We'll go over all of these terms and all of these theories during the walkthrough. Now, whether you end up using all of these tools, or just some of them, it's really good to know what you're equipped with to be able to tackle the problem set. So in Scratch, the first lingo that you need to know is what a sprite is. So every object or every character, be it a cat a dog or a ball, is called a sprite. And so, if I want, say, two cats-- whether or not they're identical-- I'll need to make two separate sprites in Scratch. And so sprites have scripts associated with them. Scripts are actually what you're going to be building-- dragging and dropping-- with your blocks. And so what scripts do is kind of determine and define how the sprite behaves. Sprites aren't actually just images, because we have costumes also associated with the sprites that kind of determine what the sprite looks like. And you can have more than one costume for a given sprite. So at some point during your Scratch program, as we'll show later on today during the walkthrough, you can actually change the costume of your sprite to make it look either slightly different or completely different. And so there are three ways of creating a sprite in Scratch. One, you can draw your own in Scratch's built in paint editor. You can upload your own image, use one of Scratch's built-in ones, or, the last option, get a random sprite. Now, if you are feeling particularly lucky, then I welcome you to try your luck and create a random sprite. So all of the sprites are placed on the stage in Scratch. The stage-- we can treat it as our canvas. And so all of the sprites are placed on the stage. And this stage, what it does is allows all of the sprites to move around on it. And just like sprites, the stage also has scripts. And so these scripts, to place them on the stage-- it's really useful when, say, you have a script that doesn't exactly pertain to one specific sprite, but rather pertains to multiple sprites or just, in general, something that you want to do. So you can place those scripts on the stage instead, and that would be slightly better design. Now, while you can have multiple sprites, it's good to keep in mind that you can only have one stage. But stages also have backgrounds. As opposed to costumes, like sprites do, stages have backgrounds. And again, you can either draw your own or upload your own image to use as a background. So does anyone have any questions before we go on? OK. Feel free to interrupt me what during the walkthrough, and I'm happy to answer any questions you have. OK. So when you start your sprite program, what you're going to do is you're going to click the green flag. But if you don't connect anything to this block right here, then nothing's actually going to happen. Because, you see, what the scripts and the stage need to do is actually know to respond to the event-- that's what we call them, events-- of the green flag being clicked. So you need to actually attach blocks to the groove at the bottom of that green flag clicked block, and then the program will know what to do and how to respond to the green flag being clicked. Well, what comes after that? Well, we have a plethora of blocks in Scratch to use, and where the meat, really, of your program lies in these statements. And so these statements are conveniently organized by color. You have actions related to movement, sound, looks, et cetera. And so you can see you can navigate between them in the tabs in your Scratch program. And so, while you'll have other things built around it, what the statements actually do is actually tells the sprites or the stage to do something. As opposed to just saying, OK, when you do this, the statements actually contain the real meat of it. Let's say you want to only execute a certain action, say you only want the cat to meow when a certain thing happens. We can take advantage of Booleans, which you learned in lecture one. And so these are expressions that evaluate to either true or false. And so these are identified in Scratch by the-- you see the angles at the end of those blocks. And so you have a variety of different types of Booleans. You have "is the most being pressed down," "does 2 plus 2 equate to 5," or "is the user pressing down a certain key on the keyboard?" Now, you can't just use these alone. What you have to do is combine them with a condition. So the condition's there under the control tab in Scratch. And so they conveniently have a little placeholder that shows the shape of the block that you need to put into it. So depending on the context of the situation, you can choose a Boolean and then place it inside your condition. And there you have a conditional statement. If you put statements inside that block, then you have a structure set up, whereby once a certain condition is met on the left, you then execute the statement. Yes? STUDENT: If a variable represents a number, can you use the variable inside the Boolean, like the green one, for example? ZAMYLA CHAN: Yes, you can. You can drag and drop the variable value inside the circular shape there. Now, one of the advantages of computers is the vast power and speed at which they can execute repetitive processes. And so, instead of, say, repeating an instruction over and over and over again and actually typing that out-- or in this case, in Scratch, dragging and dropping and dragging and dropping-- what we can do is encapsulate it in a loop. And so, loops can be used to either execute things infinitely with a forever loop, or for a set number of times-- say, repeat "say hi" 10 times or until a certain condition is true. And so again, you see that Scratch is hinting that when you have a condition such as "repeat until," then the only thing that will fit inside there is a Boolean value. All right. So now, we know that we can encapsulate repetitive processes inside of loops. You can see why something like this might not be ideal. It doesn't fit on the slide. Essentially, it just does the same thing over and over again 10 times, in fact. It moves 10 steps, says hello, moves 10 steps, says hello. So now you can see that once we have loops, something like this is a lot better. It's shorter, it's smaller, and it actually completes the same thing. Now, in Scratch this might not make much of a difference, but it actually saves you some time. So onto the variable expression-- you can actually use variables and put them inside of conditions. As expressed right there, you see we have a variable named "counter," and we're equating that to see whether it's less than 0. So variables are essentially, I'd say, containers for values. In Scratch, those types of values can either be words or they can be numbers. And so, with these variables, what we can do with them is we can set their value. So in the first example here, we have the example of text containing the value "Hello, World!" In the second example, it's assumed that we already have a variable named "counter," and in that case, we're changing it by 3. We're incrementing it by 3. And then in the last example, the variables can be dragged to be put in a Boolean expression. Now, when you create a variable, what you have to decide is whether you make the variable for all of the sprites in your Scratch program, or for just the specifics sprite in which you've selected when you make the variable. And so this is a very important decision to make. And it really comes down to what scope you want the variable to have. So for instance, an example of local scope would be if you choose just for this sprite to have the variable. So that would mean that only that sprite would be able to access that variable. Only that sprite would be able to see it, change it, modify it. If you choose for to have a global scope-- so that's if you say for all sprites, if you select that option-- then that means that the stage as well as all of the sprites will be able to see, modify, and access that variable that you've created. Any questions so far on variables or anything? Yes. STUDENT: For the variables, can you have two variables of the same name if they're on different sprites? ZAMYLA CHAN: As long as they are local sprites--- ah, yes, sorry. So the question was whether you can have two variables of the same name in a program and if you have two variables with the same name but are both local sprites, so sprite one, the cat, has a variable name "counter," and sprite two, the dog, has a variable named "counter," as long as those are both local sprites, then their scope doesn't extend to the rest of the program. And so none of the other sprites or the stage will get confused. All right. So I mentioned before the entry point when we had the when green flagged clicked block. And so what that is-- it says, OK, when the event happens that the green flag is clicked, this is what you should do. And so that isn't actually the only event that we have in Scratch. We also have other events. So we have, for instance, when a key on the keyboard is pressed. And you could actually choose the letters A through Z, 0 through 9, or the arrow keys. And then we also have other events, such as when your sprite is clicked. And so when you start with that, you notice the key trend is that they only have a groove on the bottom, and so then that, again, keys you in that nothing attaches above that block. You build from that and below. Now, say, what happens if we want some event to happen just when, I don't know, a cat is touching a certain section of the stage or something like that? We actually don't have any built in event to signify that. So what we'll have to do is actually create our own event. And that's called broadcasting. So when you want to signal that a certain has happened, then you use-- in the control tab, there is a block called "broadcast." And so then, you'll type in the name of the event that you want to broadcast, and then whichever sprite or sprites-- you can have multiple sprites reacting to this message-- or the stage will have to handle it, will have to receive it, will have to say, OK, I understand that this has happened, so I'm going to do this with it. And so whenever you broadcast an event, that's with the understanding that either that sprite or another sprite is going to have to receive that event and respond. Now, the last concept before we get into an actual example of a Scratch program is threads. So threads is when your computer is executing simultaneous processes at the same time. I guarantee you that all of us have taken advantage of threads when we we're watching a movie at the same time as typing an essay or something like that. The computer is executing several things at the same time, just like Scratch can. So as you can see in this example, these two scripts can be used for the exact same sprite, because these beginning entry point blocks can actually used multiples of times. I guarantee you that probably the green flag clicked block will be one of the most popular blocks in your program. So here we see that when the green flag is clicked, there's a process going on, as well as when the green flag is clicked, there's a separate process going on. And so Scratch will run these two at the same time. And so using these threads, knowing that you can actually have more than one entry point-- even if it is the same entry point-- it's going to become really useful if you want to, say, separate distinct tasks from one another. All right. So let's actually look into an example of a Scratch program. OK. So I've already made a little program for us here. So I'm just going click the green flag to start and see what it does. So we have an orange fish here-- a fish sprite-- seems to move and then reset and go back. And then we have a shark sprite. And this shark sprite can move, it can rotate, it can swim around. OK. So that's kind of fun. But we can definitely add more to that. For instance, we see that when the shark is moving, it can actually get off the screen and almost disappear from sight. So we want to change that, because we don't want the shark to escape. And so let's stop our script and then edit the shark scripts, perhaps add something. Notice that in this particular sprite here, the forever loop ends with a straight edge. It doesn't have any groove. So in fact this makes sense, because it's a forever loop. It's executing something infinitely. So it won't ever end. Even if there was something below it, would never get to that. So you are actually forced to introduce a thread. All right. So let's add another script. So I'm going to start with this entry point of when green flag is clicked. So what I want to do is continuously check whether the shark is going to be touching the edge. But I know that, actually, under Motion there's a neat little block that says, oh, if on edge, bounce. So what we want to do is continuously execute. And so what this "if on edge, bounce" does-- it actually already checks if I'm on the edge, then bounce back. So we need to find some kind of loop to continuously execute this statement. So if we look under Control, does anyone have an idea of what loop we might want to use? Yeah. STUDENT: The forever loop. ZAMYLA CHAN: Exactly, yeah. The forever loop. So let's track that here, and then say, if on edge, bounce. And then let's see. All right. So the fish is moving as per usual. And then, oh-- now the shark can't escape and bounces off the screen. Cool. All right. So I was looking in. I can't-- yes? STUDENT: How do you make that apply to the shark as it moves to the fish? ZAMYLA CHAN: Ah. So the reason why only the shark bounces, as opposed to fish as well, is because this script that we wrote is inside the shark sprite. You see, up here, the shark sprite is selected. All right. So let's add something else. I was exploring on the different costumes that Scratch has, and I saw this cute little shark-chomp. So I thought that, hey, well, maybe we can implement the shark chomping, for instance, when we press space. I'm just going to stop this. All right. Yes. STUDENT: Could you just show the-- is that under Costumes? ZAMYLA CHAN: Oh, yes. So I went under Costumes, and then I looked under Import. And so here, Scratch has a whole array of costumes that you can choose. And so then there's a whole bunch of animals, and then the shark has a couple of costumes associated with it. OK. So in this script here, I'm already checking continuously in the forever loop, OK, well, if the left arrow is pressed, then I want to rotate counterclockwise. If the right arrow is pressed, I want to rotate clockwise. If the up arrow is pressed, then I want to progress forward. So what we can do is just add to this script, instead of adding a separate one, because this is already checking in the theme of which keys are being pressed. So let's add one that says if the space key-- let's use the space key to chomp down. So these key left arrow pressed, et cetera, these are in the brighter blue. So let's go to Sensing the brighter blue, and look down. Oh, and here is a key space pressed. So what we want to do is have the shark switch to its chomping down costume. That has to do with how the shark looks, so we go to Looks. And here we have, conveniently, switch to costume shark-chomp. But when we chomp down, we don't want the shark to be chomping down forever, so let's add, OK, well then, after it chomps, we want it to switch back. OK, so let's see what that does. So we have it moving around. OK. So we have it chomping. It's chomping kind of quickly though, because in Scratch, it's executing them instantaneously. So then, let's go to Control and make it appreciate its chomp, wait one second. And here it chomps down a little longer before it goes back to its hunger. OK. So I'm pretty happy with the shark now. But the fish, what it seems to be doing-- it's progressing a couple of steps, in fact, five times. It's moving 50 steps. And then what it's doing here in this top block here is I'm saying, OK, well, it's going to go to a certain value of x. To find the coordinates, you can actually just mouse over the screen, and then in the bottom-- right over here-- it'll show you what the coordinates are. So you can take advantage of that to input the coordinates that you want. And so what this statement here is saying is saying, OK, well, the fish starts at this certain x value and then the height of it can change. I'm actually going to pick a random height that still stays within the constraints of the stage. And so here, what I'm taking advantage of is broadcasting events. So you see that this event handler is new fish1. So whenever the fish receives the new fish1 event, it'll execute this. And then you see that after it moves forward its set amount of times, then it actually broadcasts again, OK, new fish1. But instead, how about let's make it so that the fish only continues to the end of the screen before it resets, instead of just kind of going to the center of it. So instead of saying, repeat five times-- because we don't really know how many times will be needed until it reaches the end of the screen, let's use something else. So I'm going to separate this out, because we don't really want this. To delete blocks in Scratch, what you do is you just drag it to the left, release, and then it gets deleted. If you decide that you didn't want to do that, then you can always undelete it. But we want to get rid of this. What we want to do is we want to keep on moving 50 steps and pausing one second until we touch the end of the screen. So can anyone spot a loop that we might want to use that repeats a process just until we touch the screen. STUDENT: Repeat until. ZAMYLA CHAN: I heard "repeat until," and that's correct. So yeah, this repeat until block also takes a-- but we see that this repeat until block isn't quite complete, right? So we need to say, OK, well, repeat until when? So we say, OK, well, repeat until the fish is touching the edge of the screen. And so I'll tell you that that is under Sensing. There's this touching Boolean. And so you can select here what you want to be checking that the fish is touching. So here, we want to say touching the edge. And then we want to add this back in. And so now, if we watch our fish go, once it touches the edge, it'll move back again. All right. So I'm happy with that. And let's open HungryShark1. OK, kind of like a cooking show, I added a little bit more features. So for instance, you see that the fish now is actually gliding quite smoothly, as opposed to before, when it was kind of moving and stopping, moving and stopping-- essentially just jumping set pixels. I looked under Motion, found this glide statement, and I said, OK, instead of just moving and stopping, moving and stopping, I'm going to glide 70 units to the right, but stay at my same y position here. All right. So we have a shark that can chomp. Cool. But it is called HungryShark, after all, so let's have the shark eat the fish. So how might we tell the fish or tell the shark that it has chomped down? How might we communicate? Yes. STUDENT: On the second costume of the shark, it catches the fish. ZAMYLA CHAN: Yeah, exactly. So we know that when we are switching the costume to the chomp, that we have chomp down. Now, we will eventually have to check. Say we want the fish to disappear once its eaten. We will have to somehow communicate to the fish that it'll have to hide, for instance, or disappear from the screen once it's been chomped down on. So what kind of concept, what kind of tool can we use to have the shark communicate to the fish, OK, I've chomped down? STUDENT: Broadcasting. ZAMYLA CHAN: Yes, exactly, broadcasting an event. So let's go to Control and let's say broadcast. And let's broadcast chomp. All right. But once we broadcast something, that's with the assumption that we're actually going to have something receive it. And so that's going to be the fish. So let's say, when I receive chomp. Now, when the shark chomp down just an empty space, we don't want the fish to react to that at all. So let's say, OK, well, only if the shark is touching the fish at the time of the chomp-- that's when we'll actually do something. So then, we're going to use the condition if, right, because we're checking whether something is true or not. So if we go back to Sensing, then we can use here, if touching. And then here, we'll choose the shark. Then under Looks, this hide block-- that'll basically make the fish disappear from the stage. We'll make it hide, but we want another fish, right? Our shark is hungry. We want to give it more fish. So then let's also broadcast a new fish again. OK. So let's see what that does. Cool. So it chomps down and another fish appears. But that's a bit too quick for another fish to go. So let's just wait a second before we broadcast a new fish. All right. OK. So this is a pretty good making of a game. But all games need a score, right? So what could we use to keep score? Yes. STUDENT: Other-- ZAMYLA CHAN: Yeah. Exactly. Yeah. So we do want to keep track of basically how many fish it's eaten. To do that, we'll have to make a variable. Let's call that score. And so presumably, since this is a game that we're playing, we're going to want the fish to be able to-- say, once its eaten it can increase the score or something and then the stage will probably have to do something with the sore as well. So I'm going to choose to make this a global variable and say for all sprites. OK. So when do we want to increase the score? When a fish has been eaten. And so we already have a process here that's dealing with the fish being eaten. So let's add this statement here-- change Score by 1. Cool. So once you eat a fish, the score increases. All right. So say I am tired of this game. I stop. And then, oh, I want to come back to the game. I want to start a new game. Well, the score is still 3, even though I'm playing a new game. We don't really want to score never to reset, right? So let's add a statement when the game is started in the stage to say, OK, well, we want to reset the score. So here we set the variable score to 0. And so now, whenever you start a game, the score will start at 0. Cool. OK. OK. So now, let's go on to HungryShark2. So I've done a little bit more now, and what I've done is right clicked on the fish sprite. I wanted more fish, and so I clicked duplicate and it made a new sprite identical to that one and also copied in all the scripts as well. So then this fish2 is essentially identical to fish1, except instead of starting at the left and moving right, it starts at the right and moves left. And then I also chose a new costume for it. Then I found another costume that was a spotted fish, and I was like, cool, this looks poisonous, so let's pretend that this is a poisonous fish. And so I said, OK, well, instead of eating the poisonous fish and having your score increase, I actually want it to decrease. So here we have score decreasing by 1 whenever the shark eats it. And then, I really liked the costumes that Scratch provided, and I looked and then I found the shark's-- it looked like a sick shark. And so then I edited it I made it green. And I was like, cool, it's a sick shark. All right. So let let's add to our script some kind of way of making the shark switch into being sick whenever it eats a poisoned fish. OK. So because we copied all of the scripts from our original fish into the poison fish, it already has this sprite here that says, when I'm chomped down, am I actually chomped down? So we can take advantage of this to communicate to the shark, oh, well, you just ate a poison fish. You're sick. And so this would be what kind of action? What would be want to do? Broadcast. Yeah, exactly. So let's broadcast. Let's call it shark sick. OK. So now, the shark, obviously, is going to be the one who's receiving this event. So let's add when I receive the shark being sick. OK. So we know we have this costume-- the shark is sick. And then we know from before that we kind of appreciate when we can pause a little bit before switching back. Yeah? STUDENT: How do you copy script from one sprite to another? ZAMYLA CHAN: Ah. So in this instance, when I just duplicated the sprite, to copy one script to another sprite, what I did here was just say duplicate, and it actually made an entire new sprite with all of the scripts included. But say you want to just copy one certain script to another sprite, then what you would do is actually just drag this, hover over another script, and now here it duplicated it. In this instance, it already had it, so we can just delete that again. But to copy one script into another, what you do is just drag it onto the other sprites. OK. So we're back at the shark being sick. So it's received shark is sick, and it says, OK, well, once I'm sick, I'm going to switch to my costume that says "shark sick," and now, let's just add a wait to appreciate the green. And then we're going to be hungry again, so we can just switch back to the shark being hungry. All right. So let's eat this purple fish. That's fine. Good question. What happened to the counter? OK. So we have set score to 0 here, but this score-- what this check mark does is it hides or unhides the variable from the screen. But what we can do instead of unchecking or checking it-- we can actually have this block here says "show or hide the variable." So let's make sure that every time we start the game that the variable is shown. OK. So now the variable is shown. We eat a poison fish, and we get sick. Cool. All right. So now, it's odd for a game for us to have negative points, right? So it keeps on eating these and it's like-- so how about whenever we get negative, if we've eaten too many poisonous fish, game over-- shark's too sick. All right. So what we'll need to do is we'll need to broadcast some event-- game over. So we could do this several ways, actually. We could have somewhere in the stage a script that continuously checks is the score negative? Is the score negative? If yes, then we broadcast this event. So that's one way of doing it. Or we could take advantage of the fact that we know that the only way that your score could be negative is when you eat a poisonous fish, right? Because when you eat another fish, your score is going to increase. So there's no use in checking whether it should be game over or not. So this is a similar process here. So we can actually just add to this "when I receive shark sick." So say we add this condition. We want to say, if the score is less than 0. So we're going to go to Operators, we're going to use this less than one, we're going to drag our score here, say 0. And so, if the score is 0, then we want to broadcast something called game over. OK. So say we have game over. Let's move it here or something. Well, we want the shark only to go back to being hungry if the game can still be played. So instead of using an "if," we'll use an "if else" construct. So what this does-- it says, OK, so if this condition is true, then do this, but if it's false then do this. So let's add if the score is less than 0, then you broadcast game over, but if not-- if your score is still positive-- then go back to being hungry. OK. Cool. So now that we have this game over event, we'll have to have some way of responding to it. So let's make a new script that says "when I receive game over." And what we have here under Control is actually this stop all button, and so it basically mimics you clicking the red stop sign here. So let's have the shark stop. And so we also want the fish to stop, so let's drag and copy it in. We want all the fish to stop. And then let's have the stage stop as well. All right. So swimming around, we eat a fish, and then the program freezes. I'm clicking down but I can't actually do anything. OK, but let's say we don't want to remind the user that they've got a negative value, for instance, then we can, for instance, hide the variable from the screen. So when the stage receives game over, then it will hide the variable score. OK. So let's eat one more fish. And then the score disappears, and you just have this screen. All right. So that's a pretty decent game, and if you had more time, then you could eventually add more and more scripts. And so then, I added a few more fish, made them progress at different speeds, and then whenever the shark eats a poisonous fish, it actually says, "Blech!" And then what I did is I added a new background to the stage-- a game over background. And so what the stage does during the game over event handling is it switches to the background of game over background. And as well, I hid all of the sprites from the stage so that only the game over background was shown. There are a couple of other little additions that I added, for instance, before when we ended our program, then our shark, the next time that we started, would start up in that position as well. What I added is whenever the green flag is clicked, then the shark goes back to the origin and then faces towards the right, so that every time, you have a shark starting there. So you can experiment in Motion and things like, that just to add little touches that make your game a bit more polished. Does anyone have any questions about HungryShark? Cool. All right. So that's an example of something that you could make in Scratch using all the tools that we discussed earlier. So I also included in the walkthrough slides. You'll see them later. It's just an overview of the processes that we did-- progressing from HungryShark0 all the way to our final. One Yeah. But that's about it. I'll stay behind if you guys want to ask any more questions. This was Walkthrough 0. Thank you all for coming, and I'll see you at Walkthrough 1.