On this page:
Designing Data
Designing Functions
World Programs
6.6

Lab 3 Designing Data, Functions, and Programs

lab!

Purpose: The purpose of this lab is to practice designing and programming with Posns and custom structures.

Textbook references: Chapter 3: How to Design Programs Chapter 5: Adding Structure

Designing Data

Exercise 1 Design data to represent the 4 cardinal directions. A Direction is either north, south, east, or west. What data can we use to represent this? Be sure to follow all the steps of the data design recipe.

Exercise 2 The Weather Channel is updating their app to tell people what clothing to wear based on the current temperature. When the temperature is less than 40 degrees they will tell people to wear very warm clothing, when the temperature is between 40 degrees and 65 degrees they will tell people to wear normal clothing, and when the temperature is above 65 degrees they will tell people to wear very light clothing. Design data to represent a Temperature which encompasses the idea that there is different behavior at these different levels. Be sure to follow all the steps of the data design recipe.

Designing Functions

Exercise 3 Design a function turn-left which takes a Direction, representing which way you are facing, and produces the Direction you will be facing if you turn left 90 degrees. Be sure to use the work you did in exercise 1 to help you. Follow all the steps of the function design recipe.

Please submit the above exercise to the handin server by 10pm EDT on the day of lab.

Exercise 4 Design a function which-clothes which takes a Temperature and returns a String describing the clothing you should wear at that temperature. Be sure to use the work you did in exercise 2 to help you. Follow all the steps of the function design recipe.

World Programs

In this portion of the lab we will design a small game using big-bang. In this game a dot will be shown at a random x-position on the screen. On every clock tick the dot will change to a new random x-position. The player wins if they can click on the dot.

Whenever we design universe programs (programs that use big-bang) we will follow the same sequence of steps. You should use these steps when you are designing programs for the homeworks in this course as well.

Step 1: What Stays the Same?

The first step is to determine what stays the same throughout the program. These things will be defined as constants at the top of our program. In a lot of cases, these will be images, such as the image of the dot in our program. Since we always want to draw the dot the same way, we can define that as a constant, and use the same constant throughout our program.

The reason for defining these constants is to give our program a single point of control. This means that if we want to change the way we draw our dot, for example, we only need to change it in one place. This helps to prevent errors if we need to update our code over time.

To start you off, here are some constant definitions you can use. Don’t forget to require the image teachpack so that the image constants will work!

(define BACKGROUND-WIDTH 500)
(define BACKGROUND-HEIGHT 500)
(define BACKGROUND (empty-scene BACKGROUND-WIDTH BACKGROUND-HEIGHT))
(define DOT-SIZE 10)
(define DOT-COLOR "black")
(define DOT-IMAGE (circle DOT-SIZE "solid" DOT-COLOR))
(define DOT-Y (/ BACKGROUND-HEIGHT 2))
(define TEXT-SIZE 20)
(define WIN-TEXT "YOU WIN!")
(define WIN-IMAGE (overlay (text WIN-TEXT TEXT-SIZE "dark green") BACKGROUND))
(define LOSE-TEXT "YOU LOSE :(")
(define LOSE-IMAGE (overlay (text LOSE-TEXT TEXT-SIZE "dark red") BACKGROUND))

Exercise 5 Copy the above definitions into your file. You can feel free to change the colors and sizes if you wish.

Step 2: What Changes?

The next step is to determine what changes as the program runs. These might be things that change over time, or things that change as the player interacts with the program. We will use these changes to determine our world state: the data we will use to represent this program.

In our case several things change: the x-position of the dot changes over time, and whether the game is won or lost changes if the player clicks the mouse. How can we represent that?

First, let’s see how many different states there are in our game. It seems like there are 2 cases: the game is in progress, or the game is over. What do we need to keep track of in each case? In the first case we want to know where the dot is on the screen. In the second case we need to know whether the player has won or lost. How can we represent these pieces of information? Well, the position of the dot on the screen is a number (the x-position), and whether a person has won or lost is a true or false question so we can use a Boolean.

To summarize, here is a data definition we can use to represent this program:

; A DotGame is one of:
; - Number (represents the x-position of the dot)
; - Boolean (represents whether the player has won or lost)

Exercise 6 Complete the steps of the data design recipe for the above data definition.

Step 3: Which Handlers Do We Need?

The next step is to determine which of big-bang’s many handlers we may need. Handler functions are the functions that go in the different clauses of the call to big-bang. For example, a drawing handler would go in the to-draw clause.

Here are all the handler functions you can choose from:
  • to-draw: This one is mandatory because otherwise the program won’t know what to display!

  • on-tick: Use this when something changes over time without user input.

  • on-mouse: Use this when something changes if the mouse is clicked or moved or dragged or otherwise used in some way.

  • on-key: Use this when something changes if the user presses some key on the keyboard.

  • stop-when: Use this if you want your program to stop running at some point.

When you decide which ones you need, it’s a good idea to give a name to each function and write down its signature and purpose in a wishlist. This will give you a list of functions to design later on and will prevent you from forgetting what those functions are for.

In our case, the program changes over time (the dot moves) and when the mouse is clicked. Therefore we will need three handler functions. In the following exercises we will write their signatures and purpose statements. Remember that every handler function will take in a world state but you cannot use WorldState as a data type. You must use the type of data that you defined to represent your program. In our case, that type of data is a DotGame.

Exercise 7 Write the signature and purpose statement for draw-game, the function that will be put in the to-draw clause.

Exercise 8 Write the signature and purpose statement for move-dot, the function that will be put in the on-tick clause.

Exercise 9 Write the signature and purpose statement for change-if-click, the function that will be put in the on-mouse clause.

Step 4: Main Function

Now that we know which functions we are going to use, we can write our main function which will call big-bang. We write this function first before designing the helper functions because we are following a top down approach to programming. This helps provide clarity when other people are reading your code.

; play-game : Number -> DotGame
; Play the dot game with the given initial x-position of the dot

Exercise 10 Copy the above code into your file. The #; will comment it out so that you can still run your file even if you have not yet defined all the helper functions.

Step 5: Design of Handlers

Now we have to actually design the functions we put on our wish list!

Exercise 11 Design the function draw-game. If the game is in progress, it draws the dot (DOT-IMAGE) at the given x-position and a fixed y-position (DOT-Y). If the game has ended it draws the ending text: WIN-IMAGE if the player won and LOSE-IMAGE if the player lost.

Exercise 12 Design the function move-dot. If the game is in progress, it changes the dot’s x position to a new random position (use random to generate this new position). If the game has ended, it just returns the same game, unchanged. NOTE: You can use check-random to test this function in the case where you are producing a random number.

Exercise 13 Design the function change-if-click. If the game is in progress, it checks whether the mouse was clicked. If so, it updates the game to be either #t if the position clicked is within the dot, or #f if the position clicked is NOT within the dot. If the game has ended, it just returns the same game, unchanged.

To help with this exercise we have provided a function that checks whether a position is within the dot:

; within-dot? : Number Number Number -> Boolean
; Are the given x and y coordinates within the dot at the given x coordinate?
(check-expect (within-dot? 10 DOT-Y 11) #t)
(check-expect (within-dot? 10 DOT-Y 100) #f)
(check-expect (within-dot? 10 0 11) #f)
(define (within-dot? x y dotx)
  (<= (sqrt (+ (sqr (- x dotx)) (sqr (- y DOT-Y)))) DOT-SIZE))

That’s it! You finished the program!

Exercise 14 Uncomment your main function by removing the #; before the definition. Try running your program using (play-game (random BACKGROUND-WIDTH)).