Module 4 Fixed-Sized Data

Structures allow storing multiple values in a single piece of data.

Posn

Types of functions:

  1. Constructor: used to create the structure
  2. Selectors: used to get values from existing structures.
  3. Predicate: whether a data is of a particular structure

Example:

               ;; Constructor
(define MYPOSN (make-posn 1 2))

;; Selectors
(posn-x MYPOSN)
(posn-y MYPOSN)

;; Predicate
(posn? MYPOSN) ;; Returns #true
(posn? 5) ;; Returns #false

The signature of the posn? function is Any -> Boolean.

Any

make-posn will accept any two data types (Any Any)

Example: positional data

;; A Position is a (make-posn Real Real)
;; Interpretation: a 2-dimensional point

(define POSN-0 (make-posn 0 0))
(define POSN-1 (make-posn 1 2))
(define POSN-2 (make-posn 10 -2.5))

(define (position-template p)
  (... (posn-x p) ...
       (posn-x y) ...))

While writing the template, we need to know what we would be useful for a function that takes position as an argument. They will most likely use at least one of their selectors.

Design the function x-greater-than-y? that accepts a 2-dimensional position and determines whether the x-coordinate is greater than the y-coordinate.

;; x-greater-than-y? : Position -> Boolean
;; Determines of the x-coord is greater than the
;; y-coord

(check-expect (x-greater-than-y? POSN-0) #false)
(check-expect (x-greater-than-y? POSN-1) #false)
(check-expect (x-greater-than-y? POSN-2) #true)

(define (x-greater-than-y? p)
  (> (posn-x p) (posn-y p) ))

Design the function add-10-to-x that accepts a 2-dimensional position and returns a new position with the same y-coordinate and an x-coordinate that is 10 greater.

;; add-10-to-x : Position -> Position
;; Increases the x-coord by 10.

(check-expect (add-10-to-x POSN-0) (make-posn 10 0))
(check-expect (add-10-to-x POSN-1) (make-posn 11 2))
(check-expect (add-10-to-x POSN-2) (make-posn 20 -2.5))

(define (add-10-to-x p)
  (make-posn (+ 10(posn-x p))
             (posn-y p)))

Design program on-control that allows the user to change the position the moon using arrow keys.

;; Visualizations 
(define SKY-WIDTH 300)
(define SKY-HEIGHT 200)
(define RADIUS 25)

(define MOON (circle RADIUS "solid" "gray") )
(define SKY (rectangle SKY-WIDTH SKY-HEIGHT "solid" "light blue"))
;; moon-control : Position -> Position
;; Allows the user to control the sky

(define (moon-control initial-p)
  (big-bang initial-p
    [to-draw draw-moon]
    [on-key move-moon]))

Our wishlist contains

  • draw-moon : Position -> Image
  • move-moon : Position KeyEvent -> Position

draw-moon:

;; draw-moon : Position -> Image
;; Draws the moon in the sky at the particular
;; position

(check-expect (draw-moon POSN-0)
              (place-image MOON 0 0 SKY))

(define (draw-moon p)
  (place-image MOON
               (posn-x p) 
               (posn-y p)
               SKY))
;; move-moon : Position KeyEvent -> Position
;; Moves the pos according to the key press.

(check-expect (move-moon POSN-0 "left") (make-posn -1 0))
(check-expect (move-moon POSN-0 "right") (make-posn 1 0))
(check-expect (move-moon POSN-0 "up") (make-posn 0 -1))
(check-expect (move-moon POSN-0 "down") (make-posn 0 1))
(check-expect (move-moon POSN-0 " ") POSN-0)

(define (move-moon p key)
  (cond
    [(key=? key "left") (shift-moon p -1 0)]
    [(key=? key "right") (shift-moon p 1 0)]
    [(key=? key "up") (shift-moon p 0 -1)]
    [(key=? key "down") (shift-moon p 0 1)]
    [else p]))

;; shift-moon : Position Real Real -> Position
;; shifts the moons pos by the supplied changes
;; in and x and y

(check-expect (shift-moon POSN-0 -2 3)
              (make-posn -2 3))

(define (shift-moon p dx dy)
  (make-posn (+ (posn-x p) dx)
             (+ (posn-y p) dy)))