Lab 2 World Programs, and Design
Purpose: The purpose of this lab is to practice designing and implementing a small world program with enumerated data.
Design Recipe
Exercise 1 Design the function string-starts-with? which takes two Strings and returns a Boolean indicating whether the first string begins with the second. Be sure to follow all the steps of the design recipe for functions. When you are testing your function, make sure you test the case where the first string is shorter than the second. For example (string-starts-with? "fundies" "fun") should return true but (string-starts-with? "fun" "fundies") should return false.
Designing World Programs
During this portion of the lab we’re going to design a small "door simulator" program. Here’s how the program works:
A door can either be open, closed, or locked. Initially your program will take in a representation of one of these states.
The user can open a closed door by pressing the "o" key on their keyboard. You cannot open a locked door, and attempting to open an already open door will do nothing.
The user can close an open door by pressing the "c" key on their keyboard. Attempting to close an already closed (or closed and locked) door will do nothing.
The user can lock a closed door by pressing the "l" key on their keyboard. Attempting to lock an open door or an already locked door will do nothing.
The user can unlock a locked door by pressing the "u" key on their keyboard. Attempting to unlock a closed door that is already unlocked, or an open door, will do nothing.
When designing this program we’re going to ask a series of questions. You should ask yourself these questions whenever you are designing a program using big-bang.
Step 1: What stays the same?
One thing that stays the same in this program (and many others) is the images. We can define images of open, closed, and locked doors to use throughout our program. Here are some examples of what those images might look like:
Exercise 2 Insert these images into your program and define them as constants. (You can actually right-click on each image in your browser, copy the image, and paste it into your DrRacket Definitions window!) Use names that tell you something about the image such as DOOR-CLOSED-IMAGE.
Step 2: What changes?
The only thing changing in this program is the state of the door: whether it is open, closed, or locked. We will need to provide big-bang with a piece of data (referred to as the "world state") to describe which state we are currently in.
Remember that we want to separate data from the images of that data, so we can’t just use the images from the previous step as our data.
Instead, a good way to keep track of the state of the door would be the following data definition:
; A DoorState is one of: ; - "closed" ; - "locked" ; - "open"
Exercise 3 Starting with the above data definition, do a complete data design following all 4 steps of the data design recipe.
Step 3: Which handlers do we need?
As a recap, big-bang is our way of building interactive programs. It operates by storing a single piece of data the programmer provides, the world state, and allowing the programmer to define handler functions that modify this world state. Big-bang calls these handlers and passes them one argument (the current state of the world). In most cases, the handler function returns the next state of the world. The two exceptions to this that you will need to know are to-draw, which returns an image depicting the current world state, and stop-when which returns a boolean stating whether the big-bang program should terminate.
Most handler functions define the way the world state will change in one circumstance. For example, on-tick is called once per tick (1/28th of a second by default) and defines the way the world state will change over time. When deciding whether you need a handler such as on-tick, you must determine whether the world state will change over time with no user input. Likewise, on-mouse handles the circumstance where the user moves the mouse or clicks within the program. If this user action should change the world state, then your program needs an on-mouse handler.
As always we will need a to-draw clause. This handler is mandatory for all big-bang programs, and is called on every tick.
Based on the explanation of the program, the state of the door changes when we press a certain key. What does that tell us about the handlers we need? Remember to use the big-bang documentation for a list of what handlers are available and how to use each one.
Exercise 4 Write down the signatures of the handler functions you will need. If you are having trouble, feel free to ask a staff member to help.
Step 4: Main Function
Now that we’ve decided on our handler functions, we can put together our main function which will call big-bang. We write this function first because in this course we follow a top down programming approach. That means larger functions go at the top of our program and smaller functions go underneath.
Exercise 5 Design the main function door-simulator which, given an initial DoorState, runs the door simulation using big-bang. Recall that we cannot test functions that use big-bang because we don’t know when the user will stop the program or how they will interact with it. However, you should follow all the other steps of the design recipe for functions.
Step 5: Design your handlers
Exercise 6 Design the function that draws the DoorState. Which handler does this belong to? Remember to follow the design recipe for functions.
Exercise 7 Design the function which changes the DoorState based on user input. Which handler does this belong to? Remember to follow the design recipe for functions.
Before You Go...
If you had trouble finishing any of the exercises in the lab or homework, or just feel like you’re struggling with any of the class material, please feel free to come to office hours and talk to a TA for additional assistance. We love to teach and you will learn. It’s symbiotic!