CS 2500 - Lab5: Lists! Lists! Lists!

This lab is all about Lists and structures. We'll be using them for the rest of the semester (and on the exam), so it is important that you practice, practice, practice! Be sure to switch roles often. This lab has been designed so you can switch roles after each exercise (or every two if you need more practice).

Part I: Finger Exercises

We start with finger exercises today; lists are important, and they should be second nature.

Consider the following data definition:

     ;; An HRLoN (Hand-rolled List of Numbers) is one of:
     ;; - (make-empty-lon)
     ;; - (make-cons-lon Number HRLoN)
     (define-struct empty-lon ())
     (define-struct cons-lon (first rest))

     ;; HRLoN Examples:
     (make-cons-lon 1 (make-cons-lon 2 (make-empty-lon)))
     (make-cons-lon -3 (make-cons-lon 3/4 (make-cons-lon 0.2 (make-empty-lon))))
  1. Write a template for functions that consume a hand-rolled List of Numbers (HRLoN).

Of course, these definitions are unnecessary, since DrRacket includes short-hand functions/values for lists that we have seen in class.

** This is more like it...
     ;; An LoN is one of:
     ;; - empty
     ;; - (cons Number LoN)
  1. For each of the following write the corresponding data definition (like above), then make 3 examples of each.
    • List of Strings
    • List of Images (rectangles, circles, etc)
    • List of List of Numbers (LoLoN). Hint: This is a List where the first of a cons is actually an LoN.

Part II: List Calisthenics

  1. Write the function sum that consumes a list of numbers and returns the sum of its elements.
  1. Write the function product that consumes a list of numbers and returns the product of its elements.
  1. Design the function join-los that consumes a list of strings and concatenates them. For example:
         (join-los (cons "An" (cons "Lo" (cons "S" empty))))

Part III: Fun with Gravity (yay!)

Here a data definition to get us started. Mak sure you understand the definition/interpretation before moving on.

      ;; A Ball is:
      ;;  - (make-ball Number Number Number Number)
      (define-struct ball (x y vx vy))

      ;; Interpretation: A Ball represents an object at position X/Y with
      ;;   a velocity VX in the X direction, and VY in the Y direction.

      ;; All numbers are Pixel units, and computer graphics coordinates

      ;; Constants
      (define WIDTH 400)
      (define HEIGHT 400)
      (define GRAV-ACC 3)
      (define SIZE 10)

  1. Write a data definition for Lists of Balls (LoB).
  1. Write two templates: one for functions that consume a Ball, and another for functions that consume an LoB. Remember to use the Ball template in the LoB template.

Coding Warm-up...

  1. Design the function off-screen? that determines whether or not the given Ball is off the screen (use WIDTH and HEIGHT so we can change it later).

    Questions: When is an x/y coordinate off screen? Which template should you use?

  1. Design the function gravity that consumes a Ball and creates a new one whose Y velocity is increased by GRAV-ACC (other components remain the same).
  1. Design the function move that consumes a Ball and moves it's X/Y coordinates by the Ball's corresponding velocities (i.e., updates the X/Y by adding VX/VY).

Now for Lists...

  1. Design the function draw-lob that consumes an LoB returns a Scene (remember WIDTH and HEIGHT?) that has a circle of size SIZE for each ball in the list, at the right coordinates.
  1. Design the function on-screen that consumes an LoB and filters out all the off-screen? Balls.
  1. Design the function gravity-all that consumes an LoB and applies gravity to all its elements, returning the resulting LoB.
  1. Design the function move-all that consumes an LoB and applies move to all its elements, returning the resulting LoB.

Run program... Run!

Here's some code to finish off the exercises... Run it... what does it do?
      ;; mouse : LoB Number Number MouseEvent -> LOP
      ;; Add a new random ball
      (define (mouse lob x y me)
        (cond [(string=? me "drag")
               (cons (make-ball x y
                                (- (random 9) 4)
                                (- (+ (random 10) 10)))
              [else lob]))

      ;; tick : LoB -> LoB
      ;; Move, gravitize, then filter out all 
      ;;   the off-screen Balls
      (define (tick lob)
        (on-screen (move-all (gravity-all lob))))

      (define last (big-bang empty
                             (on-mouse mouse)
                             (to-draw draw-lob)
                             (on-tick tick)))

If you finish early...

Try adding a color to the Ball structure, and change your functions to match (make sure you draw each Ball with the correct color!). Then change mouse to create the new Ball with a random color.

Hint: make a function that returns a color String given a number (say it returns one of 5 preselected colors). Then call that function with (random 5) to get a random color when needed.