On this page:
Understanding Local and Lambda
Out Of This World
Before You Go...
Stretch Goals
6.6

Lab 7 Scoping It Out

lab!

Purpose: The purpose of this lab is to practice local, lambda, and scope.

Textbook References: Chapter 16.2: Local Definitions, Chapter 17: Nameless Functions, Intermezzo: Scope

Understanding Local and Lambda

Exercise 1 Complete the following check-expects with the expected value. Run them to double check your answers. Hint: a good first step would be to provide the signatures for the given functions.

(define (f x y z)
  (local [(define x (+ y z))]
    (local [(define y z)]
      (local [(define z (* x y))]
        (+ x y z)))))
 
(check-expect (f 1 2 3) __)
 
(define (g a b)
  (+ (local [(define b (string->number a))]
       (local [(define a (sqr b))]
         (- a b)))
     (string-length a)
     (if b 10 5)))
 
(check-expect (g "5" true) __)

Exercise 2 Design the function adder which, given a Number produces a function that adds that Number to a given Number. Some check-expects have been provided for you below:
(check-expect ((adder 3) 4) 7)
(check-expect ((adder 10) 2) 12)

Out Of This World

In this lab we will design a program where aliens are invading! The game will show a black screen with several alien invaders on it, each moving in its own way around the screen. New aliens will be added to the screen randomly as the game progresses.

Recall that the steps we take to design world programs break with our usual convention of top down programming because the larger program is at the bottom instead of at the top. However, you should continue to design your individual functions using top down programming as much as possible.

Step 1: What stays the same?

Exercise 3 Define some constants to represent the things in the world that never change.

Step 2: What changes?

There are several things changing in this program. The first is the aliens themselves. Each alien is moving in its own way around the screen, so we need a way to represent that movement. A data definition has been provided for you below:

; An Alien is a [Nat -> Posn]
; and represents the movement function of an alien such that given the amount of time
; that has passed it produces the alien's position
 
(define ALIEN1 (lambda (t) (make-posn 55 (+ t 27))))
(define ALIEN2 (lambda (t) (make-posn (+ 100 t) (- 100 t))))

Since an Alien is a function we don’t know how to write a template for it, so for now we will treat it as an atomic piece of data.

Now, of course, we need a way to combine all the aliens into a single world state, and a way to keep track of the time that has passed since the program began.

Exercise 4 Design a data definition for a Invasion which contains an arbitrary number of alien invaders, and a number representing the number of ticks since the program began. Remember to follow all the steps of the data design recipe!

Step 3: Which handlers do we need?

Exercise 5 Write the signature and purpose statements for the handler functions you will need. Recall that big-bang always requires a to-draw clause. Which other clauses will you need based on the program description? If you are having trouble take a look at the documentation, and if you are still confused, ask a tutor or TA for assistance.

Step 4: Design your handlers

Exercise 6 Design the function that draws the aliens onto a black background. Remember to use existing list abstractions where you can.

To design the function that updates the game when the clock ticks, we will need a way to add new aliens to the game. To help with that, consider the following data definition:

; An AlienGenerator is a [Nat Nat Nat -> [Nat -> Posn]]
; and is a function which takes an initial time, x-coordinate, and y-coordinate, and produces
; a movement function which, given the time, produces the position of an alien
 
; move-right : AlienGenerator
; Produces a movement function that moves the alien to the right horizontally
(define (move-right t0 x0 y0)
  (lambda (t) (make-posn (+ x0 (- t t0)) y0)))
 
; move-diagonal : AlienGenerator
; Produces a movement function that moves the alien diagonally down and to the left
(define (move-diagonal t0 x0 y0)
  (lambda (t) (make-posn (- x0 (- t t0)) (+ y0 (- t t0)))))

Exercise 7 Define a few more examples of AlienGenerators. Then define a constant ALL-GENERATORS which is a list of all the AlienGenerators you have defined.

Exercise 8 Now design the function which updates your alien invasion game when the clock ticks. Remember that you need to add 1 to the number of ticks and then randomly decide whether to add new aliens to the screen. It will help to define a random-element function, which produces a random element from a list. Note: you cannot compare functions using check-expect so if you have a function that produces a function you need to call it on something and check what that produces instead.

Step 5: Put it all together!

Exercise 9 Design the function launch-invasion which takes a number, representing the number of initial aliens to show on the screen, and launches the alien invasion game. Give it a try!

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.

Stretch Goals

Exercise 10 Add the ability to fight back against the aliens! When the user clicks an alien, that alien should be removed from the screen.

Exercise 11 Add the ability to keep score. For each alien that the player removes, they should get 1 pt. When the user exits the program, their score should be returned.

Exercise 12 Add different types of aliens. The different types of aliens should be worth different numbers of points. You should make the higher point-value aliens smaller, to make it harder to remove them.