# 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-empty-lon)
(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:
```   (check-expect
(join-los (cons "An" (cons "Lo" (cons "S" empty))))
"AnLoS")
```

## 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)))
lob)]
[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.