Now let me just say a thing about templates.
Templates are not a beginner's approach to programming.
I told you in the intro video that the method we're going to learn in this
course is what I do when problems get hard.
And that's true. So what templates are, the way we mean
them in this course, is they're an expert's way of saying gee, before I
start on this function or before I start on this program, what do I know about the
basic structure of it before I get into the details.
So data driven templates are saying, given that I know what type of data this
function consumes, what do I know about the structure of this function?
And the Big Bang World program template is a way of saying, given that I know I'm
using Big Bang, what do I know about the basic structure of this program before I
start? And later on in the course, we'll see
templates where we know, given that I know I'm using this basic kind of
algorithm, what must be true about the structure of the program before I get to
the details. Templates are an idea that you can use
throughout your career no matter how sophisticated a programmer you get to be.
When you get a hard problem and you don't quite know how to do it you first say
well what do I know about the basic structure of the program before I get to
the details. That's an incredibly powerful idea and
its not one that's just for beginners. In the last video we started on the
problem of designing the world program that causes the cat to march across the
screen. And we did the first half of the world
program design recipe, we did the domain analysis half.
That produced this domain analysis for us, in which we identified constant
information, changing information, and the required big-bang options for this
program. In this video, we're going to start on
the second part of the How to Design Worlds recipe.
The Build the actual program part. And we're going to do steps 2-1, 2-2, and
2-3 in this video. So let's get the starter file, and what
I'm going to do now is I'm going to go to the How to Design Worlds Recipe page.
And I'm going to scoot down here to the bottom, and I'm going to take this
template of a world program. And I'm just going to copy this whole
template right here and bring it over into my program that I'm working on.
Now templates do something else important, or what I should really say is
that the way the recipe is structured does something else important.
Which is templates break the process of design down into steps of the process,
not just pieces of the solution. So this function and that function are
two pieces of the solution. But what the template is, is it's a step
in the process. Because when you have the final function
The template is kind of buried in the middle of it somewhere.
That's really important. That's what happens when you design a
method. Is, you can design it so that you both
get pieces of the solution, and steps of the process.
And so you get a kind of cross cutting decomposition that helps break the
overall work down into smaller and more manageable pieces.
So don't let anyone tell you that templates are just for beginners.
Nothing could be further from the truth. What is true is that as you get to be a
better programmer, you will template very simple functions or you'll kind of
template them in your head or something. But the idea of templates, the idea of
getting the structure of a piece of code before you get to the details, you'll
always have that idea. And you'll always use it when the problem
gets too hard to just immediately write down the solution.
So, here we go. We need a better title than this.
A cat [SOUND] that walks from left to right across the screen, right?
The first line of a program should give us a short summary of the program.
Now we're going to do the constants. And the constants are going to come
directly from the analysis phase of the program, this analysis here.
So, for example, one of the constants we identified was that the width of screen
didn't change. So here I have to just guess a number,
I'm going to guess a number like 600. In the rest of the program we're never
going to use the number 600, we're always going to use the constant name width.
So if it turns out that this is the wrong number, it'll be real easy to change.
We'll only have to change it in one place.
Here we go with the height. And I'll say 400.
Another constant we identified is the y coordinate of the cat.
The y coordinate of the cat never changes.
So that's the center y. And now here you might be tempted to put
200. But what I'm going to do is follow the
rule that every time I need to refer to the height I'm going to use the height
constant. So what I'm going to do here is put
height over 2. Now if I change height, center y will
also change. And let's see.
For the empty scene, the background of the scene.
There's a primitive called empty scene. And we'll make it width by height.
And that will give us a sort of blank background.
If you wanted to make a background. If you wanted to make a background that
was a nice midnight blue or something. You could, for example, make this
overlay, rectangle, width, height, solid, blue.
And that would give you a blue background.
I'll just stick with the simpler background for now.
And the last constant we identified was the cat image itself.
Okay? And for that, we're just going to use
this image here, which the starter file gave us.
I'll go up there and copy it. And then I'll come down here and paste
it. And there's the cat image.
And now would be a good time to run. In fact I should have run after each of
these definitions. And I don't get any errors, so I know
that my constants are well-formed. Now let me reinforce a point I made
before about using the constants and always referring to the constants Notice
that this code that I have here lines up really well with the analysis we did.
The fact that I can look at the analysis, and look at the code, and understand
where everything in the analysis showed up in the code is a thing called
traceability. Both of those are important for the same
reason. And this is an important intuition.
The way to think about it is there's only two kinds of programs in the world.
There's programs that change and programs that nobody uses.
To put it another way, any program that anybody uses is always changing.
People always want it to do more and better things.
And so what we're doing here is we're designing this program to make it easy to
change using constant names makes it easy to change.
Having a clear traceability between the code and the analysis we'll see later
that makes it easy to change. Okay, let's keep going.
Now I've got the constants. The next step is to do a data definition
that corresponds to the changing state of the program.
The changing state of the program from my domain analysis is the cat's x
coordinate. So that's going to be, that's simple
atomic data. That's going to be something like a
number. The World Program template has the
beginning of a data definition here. it has WS for World State but it says to
give WS a better name and sure enough I will because WS isn't a very good name.
I'll just call it cat and I'll say cat is let's say number.
And let's see the interpretation is this is the x position of the cat in screen
coordinates. And now I need some examples.
And let's see, one good example is 0. And another example is, well, let's see,
the middle of the screen is width over 2, so that's kind of in the middle.
And that's kind of on the right, on the left edge.
And let's do this one. And this is on the right edge.
So we'll run, just to make sure everything's well-formed, and it is.
Now we need a template, define fn for cat, and this is just an atomic,
non-distinct case, so dot dot dot c, we'll fill in the template rules used of
atomic non-distinct and number And its also good to comment out the template and
now we're good to go. So there we go there's our data
definition for cat for the changing world state of the program.
Now we're going to proceed to our main function.
Now we decided not to use the name ws for the changing state of this program.
We decided to use the name cat. So what I'm going to do here is, I'm
going to say Cmd+F or Ctrl+F on Windows. I'm going to take every occurrence of WS,
and I'm going to replace it with cat. Let's see, we'll replace that one, and
that one. And I won't do that one because it's a
parameter name. And I don't want to mess up the case.
I'll come back and do that one. But I'll do all of these.
[SOUND]. Oops, I didn't mean to do that one.
I'll come back and fix it. I'm not going to do that one.
Now, what's left is these ones that are parameter names, and these, I'll just
change to C. And there's that one there that I messed
up. And I'll just run down to make sure
things are still well formed. So now here what I've got from the
template is a main function that has lots of big bang options in it.
I'm not going to use all these options. I'm only going to use on-tick and
to-draw. That's what my analysis told me.
So I'm just going to go ahead and delete all of this.
And, you know, I might decide that I don't like the name tock for the on-tick
function for this program. So, let's see, I could change the name
tock. Oops, I've got a parenthesis problem
here. I'm going to change tock.
I clicked on Check Syntax. Now, click on tock, I'll say Rename tock,
and I'm going to called it advance-cat. And I'll have to fix some of my spacing
here. [SOUND] Now what's going here, on here
off to the right, is that the template for the [UNKNOWN] main function is
reminding us of the signature of each of the handlers.
And the other thing the template for the world program did is for these two
handlers, look at what we've got here. For each of these two handlers we've got
its signature, its purpose but that's not filled in.
And a stub which isn't filled in. Let me just fill this in now.
It's produce the next cat, by advancing it one pixel to right.
And that means that a good stub is just 0, because cat is number.
And this just says render the cat image at appropriate place on MTS.
These two things here, the combination of signature, purpose, and stub With those
exclamation marks are what we call a wish-list entry.
What we're doing here is we're saying, hey, up here when I wrote main I assumed
that this function advance-cat was going to exist.
And what I'm doing here is I'm writing a reminder to myself of what it is I want
that function advance-cat to do. I want it to have this signature, this
purpose, and by the way there's a stub. And this is a reminder of what I want the
render function to do, I want it to have this signature, this purpose, and by the
way there's a stub. Now, once my program is set up like this,
notice two interesting things about it. One is it turns out I can actually run
it, and I can even say main of zero and run it.
Nothing happens of course, because my tick function doesn't do anything, and my
render function only returns the At background scene no matter what.
But it does run and the reason it runs is I have these stubs, for the two big bang
handlers. I have a stub for advance cat and a stub
for render. The other thing I can do now, is I can
search for bang, bang, bang. And I can see every place in my program
that's incomplete. By marking each of the wishlist entries
with some well-known marker that says, hey this isn't done, I now know what I
have to finish. So now what I've got is the overall
structure of this program set up. I've got the constants.
I've got the data definition for the changing world I've got a main function
that calls big bang with two options on tick and two draw.
And I've got wish list entries for advanced cat and render which are the
handler functions for those two big bang options.
And now I know what I need to do in order to finish this program.
I have to design the advanced cat function or I have to finish the design
in the advanced cat function. And I have to finish the design of the
render function. And then, I should be done.
That's what we'll do in the next video.