In the previous unit, we talked about some general guidelines of developing a Jack applications, and in this unit we are going to see an example of a full blown Jack application in action. We'll both be there to see the program run, and then we'll delve into it's Jack code. Now, the application that we have chosen to show you, is something that you call Square Dance. And in showing you this particular program, we want to illustrate some notions of the object-oriented design in Jack. We want to illustrate one way of developing interaction with the user, using various input and output services supplied by the host operating system. Now, I want to say a few words about object-oriented design. This is clearly not part of this course. This course is not about programming, so we assume that you know something about object-oriented design. And if you don't, you can see some examples in our course and elsewhere, and get some ideas on how to design your own applications. All right, so we'll start with a quick demo over the Square Dance game. So, welcome once again to the VM emulator environment. I have already loaded the Square program, so we can go ahead and execute it. As we do so, we see that lots of things are happening with the code, but then nothing shows on the screen. And indeed, let me stop execution and explain what's going on. So, basically, you have to recall that each time you start executing a program, the operating system has to initialize, the program has to initialize. So, we have to spend several thousand cycles before anything shows on the screen. So we can definitely keep on executing the program, and at some point, we'll see some output on the screen. But if you want to skip all this preliminary stuff, what we have to do is turn from program flow to no animation, and no animation means in the context of the emulator, no animation of the program's behavior, of the internal behavior of the code. And now, we will rewind the code, so to speak. Basically, we set the program counter to zero, and we sart executing the program again. And immediately we see a black square appearing at the top left of the screen. This is the default square which is, I believe 30 pixels wide, and 30 pixels high. And you have to believe me that I am now taking my finger, one of my fingers, and pressing the right arrow key. So let's do that. And indeed you see that the square has moved until it hit the wall. Now I'm going to press the down arrow. Left arrow. Up arrow. And you see that the square responds to my keyboard events, and I can play with several arrows, one just after the other, and the square will move accordingly. I can also click the x key, and each time I click x, the square increases by two pixels, on the base and the height. And I can now move this square around. It looks like it moves slower, but it's only because it's bigger. So it's kind of an optical bias. And I can make it smaller. So if I click the z key, each time I click, it becomes smaller. The visual effect is not very delicate, because I didn't use any graphic optimization, and at some point the square will become so small that maybe it will even completely shrink and disappear. But actually I see that there is still a small square surviving here. Apparently that's how the program is written. And so I can once again increase it and bring it relatively back to normal, and so on and so forth. So, this has been a demo of our little Square program. Now, to recap the demo that we just saw, when you launch the Square Dance game, the first thing that you see is a black square located at the top left corner of the screen. And the square is not going anywhere, it sits there until the user does something, in particular, if the user clicks the arrow keys, the square begins to move around the screen, and so the user can control the movements using these four keys. The user can also make the square larger and smaller, and finally the user can quit the game. So, nothing new here, everything that I just discussed was shown in the demo. But we have to keep these things in mind, when we delve into the code, because the code is designed to implement all of these action here. All right. So, what is the architecture of our program? Well, we've decided to structure it around three independent and standalone Jack class files. First of all we have a square class that provides the square obstruction. So, using this class you can create a graphical square, and manipulate it, and move it around on the screen, then we have a SquareGame class that controls the user's actions and responds to the user's actions by moving the square around. And this is done within an ongoing loop. And finally, we have a main class which is rather simple that serves to initialize things, set the stage, and get the SquareGame rolling. So, these are the three classes that we use, and by and large, this design here follows what is sometimes known as MVC. Which is a well known design pattern, that recommends that you develop graphical applications using some class that handles the data of the objects that you want to manipulate. Another class, or more than one class to handle the control of the game. And other features to control the viewing of the objects. And indeed, this is roughly what we do. The square class is our core response to what is known as model. The SquareGame is the game controller, and we use a set of standalone methods, and obviously the operating system, to actually do the drawing and supply the viewing functionalities of this game. All right, so moving along, I would like to begin to explore. Each one of these three classes step by step. So let's start with square. Here's the API of square. First of all we feature a constructor that creates a new square and locates it in the given coordinates and the square will be created in the given size. The size is the length of the square size in the squares edge in pixel. And then we have a dispose method that gets rid of the current square. We provide a draw routine that draws the square and it draws it in its current coordinates and size. Erase basically, draws the square also but using the background color, so effectively it erases the square. We have an increase size and decrease size routines that serve to do what the names imply. And then we have a move up, move down, move left, and move right routines that each once again does what they advertised so everything is very self explanatory. So as you see this is the square obstruction and other classes in the world are welcome to use it including of course the classes of our application. So let's open up the code and going back to this square class, here are the fields that characterize the current object. First of all, it has x and y coordinates. And I wish to remind you that the top left of the screen is considered as a zero, zero. And then it has a size in pixels. Then comes the constructor and here's the code of the instructor. So we set x and y to the given values. We set size to the given value and then we call draw. Once we call draw, you will see the square located in the current coordinates and presumably whoever calls this constructor will call it with zero, zero coordinates to begin with. And this means that you will see the square kind of anchored to the top-left corner of the screen. So after drawing it, we returned this, which is something, which standard in every Jack constructor we always have to return the base address of the newly created object to the calling code as we've seen before in other examples. Moving along, the dispose method is a standard. There's nothing special about it. You've seen such methods before. Then we have the draw method which actually takes this logical square and finally shows it to the user. How do we do it? Well, we set color to true, meaning that we select black, and then we use the draw rectangle operating system function to draw a rectangle that has a length and a height which are the same so effectively we are drawing a square, using the standard draw rectangle routine. What about erase? Erase does exactly the same thing using the background color, using false, which is interpreted as white. Then we have an IncSize method. And the IncSize method simply erases the current image of the square, increases the size of the square and then redraws it. Okay so effectively you will see a square which is slightly larger than what we had before. And notice the condition, this method just wants to make sure that the increase operation does not cause the square to sort of overflow and mess up the screen. Then we have a decrease routine which is symmetric and there's no need to discuss it. So that's how we increase and decrease the size of the square. Moving along, how do we move the square up? Well, think about it, the square is located somewhere on the screen and what we have to do is move it up two pixels. So the simplest way to do it, which is not necessarily the most efficient one, is to draw the current square in its current position using the background color, which will effectively eliminate it from the user's eye. Then we can change the y coordinate of our square and switch back to the foreground color, black and redraw it in its new location. And that's exactly what we do in the implementation of the move up method. And if you want, you can stop the tape and take a look at this code. And once we do it, the rest of the move methods, move down, move left, move right, are very similar, follow the same tricks and therefore there's no need to discuss them. All right, okay, so this has been the square class in all its glory. And now we move on to talk about the square game class that actually controls the game. So to begin with, every square game class needs to have a square. So one property of a SquareGame class is a square which is an object of type square and then the square also has a direction. And the direction is something which is controlled by the user. And because this direction is something that we use in many places in the code, we decided to use some constants to code the five possible directions, starting with zero, which means the square is stationary. And so these are the two properties of every SquareGame. Then we have a constructor which creates a new game, and here's the code of the constructor. We start by constructing a new square, we construct it in the top left corner of the screen. And we decided by default the square will begin its life in the size of 30 pixels. Then we set the direction to zero. Meaning that at the beginning we want the square to sort of sit tight in the corner and do nothing until the user decides to start clicking something on the keyboard. And then as we normally do we return this as we normally do in constructors. Dispose is standard but before we dispose our object we make sure to also dispose the square that we created and we act as responsible citizens And, let's see. Move square. Move square is a routine that is designed to move the square. And it's not obvious to me that it belongs to this class. We could have put it also in the square class so it's a matter of judgement. So this routine could be either here or there. So we decided to put it here. So how do we do it? Well, if the direction is one, we want to move the square up. If the direction is two, we want to move it down. And so on, and so forth. And after we move the square, we do a Sys wait(5) because we want to delay the animation at some work, and then we return, okay? So, this is the move square routine, and then we come the most important routine of the square game class, which is called Run. And this is routine that actually runs the show. Now let's see how it actually does it. Well we have chosen to do it in the following way. First of all we declare a variable called key which contains the scan code of the key that the user has last pressed, okay? And if the user releases this key, it will be 0. That's the contract of key. Then we use Boolean exit name variable to decide when we want to exit the game and we initialize it to false because the game has just started. Then we enter a y loop and we say that as long as, not exit, later on as long as the user didn't hit Q, for quit. What do we want to do? Well, think about it. We started the game and the square is a lodged at the top left corner of the screen and presumably it will take some while, a few nanoseconds or seconds or hours before the user decides to do something. So how do we know that the user has actually began to use the keyboard? Well we have to sample the keyboard we have to use key press to find out what the user is doing. So what you will do what you will see next in this from now until the end of this unit is the typical way that we deal with keyboard effects or with keyboard events. As long as key is zero it means that the user has not touched yet the keyboard. What do we do? We sample the keyboard. And we put the scan code, which the user has entered, or zero into key. And then we move square, okay. We move square because these are the rules of the game. The rules of the game is that the square is always moving until it hits the wall, okay. And at the beginning direction is zero so we move the square in direction zero which means that the square is not really moving. But at some point you see after many such key presses because we are running within a loop here. As long as we are within this loop. We know that the user has not touched the keyboard, but once the user touches the keyboard, we'll be yanked out of this why loop. Because key will no longer be zero. So, finally, we have a direction, or a direction which is not zero. So if the key happens to be 81, which is a scan code of q, we are set exit to true. If the key is z, we decrease the square. If key is 88, we increase the square. And then if they key contains one of the scan codes of the arrow keys, then we set the direction property of the square to the corresponding agreed upon constant. And then we go on to enter into another loop, which controls the time that the user is actually holding his or her finger down, okay? So think about it. We arrive to this code because the user has clicked a key, right? So the user holds the finger down, and therefore key is not 0 but at some point the user will lift his or her fingers. So as long as the key is down, as long as the key is not zero, we want to continuously monitor the keyboard. Or sort of sample the keyboard using key press, and at some point the user will lift their finger and their key will become zero. So, at this point we're getting out of the loop and as long as we are within the loop, we move the square, because once again we want the square to continuously move because these are the rules of the game that we have chosen to implement. So at some point, we'll be out of the while that controls the user's actions and will be back into the outer while that asks the question, are we still playing the game? As long as exit is false. We want to continue playing the game. At some point, the user will click q, exit will become true and at that point we are going to get out of this outer loop as well. And then the run method will return and this will be the end of the game. So that's the Square Game class. Moving along, the last class that we have to explore is fairly simple. It's the main class. The main class basically initializes things and sets the game in motion, so it does it as it's customer inject using in main function. So, we create a new game object. We call the run method of this game object and then the method I just described starts executing. Once this run method terminates, we dispose the game object and return. And that's it. So, this has been a complete description of the square dance application and I do hope that it served to highlight some of the art and science of developing. Interactive apps in jack. So to recap we showed you this example because we wanted you to appreciate and understand the user interface style that Heck Jack applications feature we wanted to show you that have to use the operating system extensively just like you use the operating system extensively when you write programs in Java and Python and other high level languages. And we also wanted to illustrate some basic object oriented design. And we didn't show you our testing strategy but we wish to emphasize that this is something that you have to worry about as well. You have to be able to unit test everything that you do just like we do in any other project in this course. So with that, that's the end of this unit, and in the next unit, we'll discuss how to handle. Some graphical requirements which are more challenging than the moving squares around the screen. So I'll see you in the next unit.