On this page:
Shrinking Balloons (25 minutes)
Hand-Rolled Lists (10 minutes)
Lists (15 minutes)
Lists in the World (50 minutes)
Before You Go...
6.7

Lab 2 Enumerations, Structures, and Recursion

home work!

Purpose: The purpose of this lab is to give you some hands-on experience with designing interactive programs and programs that process structures and itemizations of data.

Textbook references: Chapter 2.5: Programs, Chapter 3: How to Design Programs, Chapter 6: Itemizations and Structures

Shrinking Balloons (25 minutes)

Goals: Practice defining constants. Create data and structure definitions. Create main functions for world programs. Create and process wishlists of functions.

Sample Problem Create a table of what changes in the balloon game (functions) and what stays the same (constants).

Constants (what stays the same)

Functions (what changes)

The size of the screen

The time

The color of the circle

The size of the circle

Sample Problem Add appropriate constant definitions to your definitions area.

(require 2htdp/image)
(require 2htdp/universe)
 
(define WIDTH 500)
(define HEIGHT WIDTH)
(define BACKGROUND (empty-scene WIDTH HEIGHT))

Sample Problem Define a structure type for the world and then develop a data definition. Recall that initially the world is a size 50 red circle. While you’re at it, define a constant initial world and some intermediate world which is not quite as big.

; A ShrinkingWorld (SW) is a (make-shrinking Number Number)
(define-struct shrinking (size time))
; - where size is the size of the circle
; - and time is the running time of the world
 
(define initial-world (make-shrinking 50 0))
(define intermediate-world (make-shrinking 70 10))

Sample Problem Add the rendering function to your wishlist:

; draw-world : SW -> Image
; Draws a red circle whose size depends on the world
(define (draw-world world) BACKGROUND) ; TODO: finish function

Sample Problem Create the remainder of your wishlist.

; shrink-world : SW -> SW
; Creates a new SW in which time has been incremented by 1
; and the size has decreased
(define (shrink-world an-sw) an-sw) ; TODO: finish function
 
; grow-world : SW Number Number MouseEvent -> SW
; Creates a new SW in which the size is slightly larger if the left
; mouse button has been pressed
(define (grow-world an-sw) an-sw) ; TODO: finish function
 
; stop-sw? : SW -> Boolean
; Is the circle too small to shrink any more?
(define (stop-sw? an-sw) false) ; TODO: finish function

Sample Problem Define the main function, which “composes” the handlers and the rendering functions.

; main : SW -> SW
; Run the game with this initial world
(define (main world0)
  (big-bang world0
            (to-draw draw-world)
            (on-tick shrink-world)
            (on-mouse grow-world)
            (stop-when stop-sw?)))

Exercise 1 Define 3 numeric constants, SHRINK-TIME0, SHRINK-TIME1, and SHRINK-TIME2 such that (< SHRINK-TIME0 SHRINK-TIME1 SHRINK-TIME2). These constants represent times in the game and shrink-world uses these times to determine how quickly to shrink the world. As the time increases, the balloon should shrink faster.

Exercise 2 Design the function shrink-world, which takes an SW. It increments the world’s time and shrinks the world’s size depending on how the world’s time compares with SHRINK-TIME0, SHRINK-TIME1, and SHRINK-TIME2.

Hint: That’s two distinct tasks. Did you notice the "two" here? You may choose by how much the world should shrink in each interval.

Exercise 3 Design the function grow-world, which takes an SW, an x coordinate, a y coordinate, and a MouseEvent. If the mouse button has been pressed, then the returned SW should have a slightly larger size than the give one. You may choose by how much the world’s circle should grow. Remember that mouse events are special strings. Be sure to ignore all mouse events except "button-down".

Exercise 4 Design the function draw-world, which takes an SW. It draws a solid red circle on top of the BACKGROUND, with radius equal to the SW’s size. (What happens if the size is negative?)

Exercise 5 Modify the game to change the color of the circle to blue if the size is greater than the original size, yellow if the size is exactly the same, and red if the size is smaller than the original size.

Hand-Rolled Lists (10 minutes)

Goals: Practice defining and processing self-referential data.

Sample Problem Develop a data definion for hand-rolled lists of numbers.

(define-struct empty-lon ())
(define-struct cons-lon (left right))
; A HRLoN (Hand-rolled List of Numbers) is one of:
; - (make-empty-lon)
; - (make-cons-lon Number HRLoN)

Sample Problem Create three examples of HRLoNs.

; Examples
(define HRLON1 (make-empty-lon))
(define HRLON2 (make-cons-lon 1 HRLON1))
(define HRLON3 (make-cons-lon 7 HRLON2))

Sample Problem Develop a template for HRLoNs.

; hrlon-temp : HRLoN -> ???
(define (hrlon-temp ahrlon)
  (... (cond [(empty-lon? ahrlon) ...]
             [(cons-lon? ahrlon)
              ... (cons-lon-left ahrlon) ...
              ... (hrlon-temp (cons-lon-right ahrlon)) ...]) ...))

Sample Problem Design the function hrlon-sum which sums up all the numbers in a hand-rolled list of numbers.

; hrlon-sum : HRLoN -> Number
; Sums up all the numbers in the list
(check-expect (hrlon-sum HRLON1) 0)
(check-expect (hrlon-sum HRLON2) 1)
(check-expect (hrlon-sum HRLON3) 8)
(define (hrlon-sum ahrlon)
  (cond [(empty-lon? ahrlon) 0]
        [(cons-lon? ahrlon)
         (+ (cons-lon-left ahrlon)
            (hrlon-sum (cons-lon-right ahrlon)))]))

Lists (15 minutes)

Goals: Practice defining and processing lists.

Exercise 6 Good news, everyone. We just got word from upstairs that all the components of lists are working again! Now this Hand-rolled List of Numbers thing seems a bit unnecessary. Develop a new data-definition for a List of Numbers, using cons and ’().

Exercise 7 Develop a template for your new type of data.

Exercise 8 Design the sum function. It should operate just like hrlon-sum but accept your new type of data as input rather than HRLoNs.

Exercise 9 Design the function overlay-all, which takes a list of images. It overlays each image onto the next image in the list.

Hint: Follow the design recipe, starting with a data definition for a list of images.

Exercise 10 Design the function sum-all that consumes a list of lists of numbers and returns the sum of all the numbers from all of the lists.

Lists in the World (50 minutes)

Goals: Practice defining and processing lists. Practice using lists in a world program.

A scientific simulation firm needs to simulate the effects of gravity on an arbitrarily large number of falling balls. Your job is to create a BSL simulation where the scientists can spawn new falling balls by clicking the mouse. They will fall to the ground for a bit until they go off the screen. The app should be in a 500 x 500 window. Once the balls go off screen the scientists no longer care about them.

The firm has figured out the main function for the simulation:
(require 2htdp/image)
(require 2htdp/universe)
 
; main : Ball -> LoB
(define (main b)
  (big-bang (cons b '()) ; <- the world state is a LoB
            [to-draw draw-lob]
            [on-tick go]
            [on-mouse new-ball]))
 
; go : LoB -> LoB
; Move balls, apply gravity, and then filter out those balls that are off screen
(define (go lob)
  (on-screen-balls (apply-gravity (move-all lob))))

As you can see, the scientists kind of followed the design recipe for world programs. But you know how scientists are. So they leave it to you to finish the job.

Exercise 11 Develop a data definition for a Ball. A Ball should have a position in x and y and a velocity in x and y (pixels per clock tick). What is a velocity? What is a speed? If you don’t recall or if you have never heard, do not hesitate to ask a tutor or TA.

Exercise 12 Develop a data definition for a LoB, pronounced "list of balls".

Hint: Be sure to create some interesting examples for your new data definitions.

Exercise 13 Develop templates for both data definitions. The template for LoB should refer to the template for Ball. Why?

Don’t forget to switch roles with your partner after each function you design so that you both get experience writing functions for lists.

Exercise 14 Design the function draw-ball which takes a Ball and an Image and draws the ball at the correct location onto the image.

Exercise 15 Design the function draw-lob which takes an LoB and draws all the balls in the list onto an empty screen of size 500x500. This function should call your draw-ball function from the previous exercise.

Hint: Use global constants for the size of the canvas rather than putting constant values directly into your code. We do this because you may need to use the canvas size values more than once.

Exercise 16 Design the function off-screen?, which determines whether a ball is off the screen.

Exercise 17 Design the function on-screen which takes an LoB and returns an LoB which contains only the balls which are on-screen.

Exercise 18 Design the function gravity which takes a Ball and creates a new one whose y velocity has been increased by gravitational acceleration.

Hint: Gravitational acceleration is 9.8 m/s2

Exercise 19 Design the function apply-gravity which takes an LoB and returns an LoB where every ball’s y velocity has been increased by gravitational acceleration.

Exercise 20 Design the function move-ball that consumes a Ball and creates a new one that has been moved according to its velocity. The new ball’s velocity is the same as the one used as input. If you do not recall what it means for an object to be located at (x,y) and to move by a velocity of (dx,dy), ask a tutor or TA.

Exercise 21 Design the function move-all that moves every ball in a list of balls according to its velocity.

Exercise 22 Design the function new-ball that adds a ball wherever the user clicks the mouse. The new ball will have a random velocity. You will give this function to on-mouse.

Hint: Use the function random.

You should now be able to run your simulation by calling the main function with some Ball.

Exercise 23 Try adding a color to your Ball structure. Change the drawing function to draw each ball with the correct color. Change the new-ball function to create a new ball of a random color.

Hint: Come up with a function that returns a color string given a number. Then you can call that function with a number generated by random.

Exercise 24 Try adding a size to your Ball structure. Change the drawing function to draw each ball with the correct size. Change the new-ball function to create a new ball of a random size. Make sure this size is not too small or you won’t be able to see the balls!

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 or tutor for additional assistance.