;; CMPU101, Spring 2013 ;; Lecture #14 (require 2htdp/universe) (require 2htdp/image) ; ; STRUCTS: Creating new compound data types. ; ; The DEFINE-STRUCT special form is used to create a new data ; type that is a container for more than one piece of data. ; ; GENERAL FORM OF DEFINING A STRUCT: ; ; 1. Use the define-struct special form, which takes the name of ; the struct and a parenthesized list of fields as arguments. ; ; E.g., to define a car struct with fields for max (speed), ; color, make, and model, you would type: ; ; (define-struct car (max col make mod)) ; ; where max: number col, make, and mod: strings. ; ; 2. This define-struct creates functions that you can use to ; make new car-structs, to access the fields of a particular ; struct, and to determine whether a given thing is a car. ; ; 3. After my-car is defined, I can use the following functions ; to access the specific fields of my-car: ; ; (define my-car ; (make-car 200 "green" "Toyota" "Corolla")) ; ; (car-max my-car) ==> 200 ;; Yes, I'm dreaming ; (car-color my-car) ==> "green" ; (car-make my-car) ==> "Toyota" ; (car-mod my-car) ==> "Corolla" ; ; ; posns: ; ; The first struct we'll use is a built-in struct known as a ; POSN that holds two numbers representing an (x,y) coordinate ; pair on a plane. There are 6 functions associated with posn's: ; ; ; (make-posn x y) -> posn, where x: number, y: number ; ; (posn-x p) -> number, where p: posn ; ; (posn-y p) -> number, where p: posn ; ; (set-posn-x! p number) -> Sets the posn-x field in p to number ; ; (set-posn-y! p number) -> Sets the posn-y field in p to number ; ; (posn? z) -> boolean, where z is anything ; ;; Ex1: Recall that the distance between a point in the plane ;; and the origin is calculated as follows: ;; (sqrt (+ (sqr x) (sqr y))) ;; ;; Write a function that consumes a posn and calculates its ;; distance from the origin. ;Contract: (dist-from-origin posn) -> number ;Header: (define dist-from-origin (lambda (p) ...)) ;Purpose: Calculate distance from p to (0,0) (define MY-POSN (make-posn 5 12)) ;Pre-function Tests: (check-expect (dist-from-origin (make-posn 3 4)) 5) (check-expect (dist-from-origin (make-posn 4 0)) 4) (check-expect (dist-from-origin (make-posn 0 6)) 6) (check-expect (dist-from-origin MY-POSN) 13) ; ;;Function definition: (define dist-from-origin (lambda (p) (sqrt (+ (sqr (posn-x p)) (sqr (posn-y p)))))) ;;----------------------- ;; Ex2: Write a function posn=? that takes 2 posns as inputs and ;; returns true only if the two are equal ;; contract: (posn=? posn posn) -> boolean ;; header: (define posn=? (lambda (p q) ...)) ;; purpose: determines if p and q are equal. (check-expect (posn=? (make-posn 1 2) (make-posn 2 3)) #f) (check-expect (posn=? (make-posn 1 2) (make-posn 1 2)) #t) ;; Function: (define posn=? (lambda (p q) (and (= (posn-x p) (posn-x q)) (= (posn-y p) (posn-y q))))) ;; ;;----------------------- ;; Ex3: Write a function called swap-x-y that takes in a posn ;; and returns a posn with the coordinates of its input swapped. ;; contract: (swap-x-y p) -> posn ;; p: posn ;; purpose: produce posn that has the x,y coordinates of p swapped. ;; Tests: (check-expect (swap-x-y MY-POSN) (make-posn 12 5)) ;; Function: (define swap-x-y (lambda (p) (make-posn (posn-y p) (posn-x p)))) ;;----------------------- ;; Ex4: Write a function called add-posns that takes in 2 posns ;; and returns a posn whose x coordinate is the sum of the x ;; coordinates and whose y coordinate is the sum of the y ;; coordinates of the 2 input posns. ;; contract: (add-posns p q) -> posn ;; p,q:posn ;; purpose: To return a posn that has the sum of the x and y coordinates of ;; p and q ;; Tests: (check-expect (add-posns MY-POSN MY-POSN) (make-posn 10 24)) ;; Function: (define add-posns (lambda (p q) (make-posn (+ (posn-x p) (posn-x q)) (+ (posn-y p) (posn-y q))))) ; Color: ; ; Another built-in struct is the color data type: ; ; (make-color red green blue alpha) -> color, where red, green, ; blue and alpha are numbers ; between 0 to 255 ; ; Functions available for the color data type: ; ; make-color, color-red, color-green, color-blue, color-alpha, ; color?, set-color-red!, set-color-green!, set-color-blue!, ; set-color-alpha! ; ; The alpha field controls the transparency of the color, where the ; default is 255, no transparency. ; ;; Structs allow us to write functions that consume and produce ;; containers with a specific number of fields. ;; ; Write a function that generates a square and places it on an ; empty scene. Use a random-number generator to create the color. ;----------------BEGIN SQUARE CONSTANTS--------- (define MODE "solid") (define SIZE 400) ;; size of screen (define MTSQ (empty-scene SIZE SIZE)) ;-----------------END SQUARE CONSTANTS---------- ; ; Contract: (ran-clr) -> color ; Header: (define ran-clr (lambda () ...)) ; Purpose: To create a color object with random entries between ; 0 and 255 for red, green, and blue fields ; Prefunction tests by visual inspection. (define UPPER 256) ; Function definition: (define ran-clr (lambda () (make-color (random UPPER) (random UPPER) (random UPPER)))) ;; Note: You can leave off the field for alpha ; Post-function printfs: (printf "(ran-clr) => ~a~%" (ran-clr)) (printf "(ran-clr) => ~a~%" (ran-clr)) (printf "(ran-clr) => ~a~%" (ran-clr)) ; Contract: (show-square) -> image ; Header: (define show-square (lambda () ...)) ; Purpose: randomly set color of square ; Pre-function tests: By visual inspection. ; Function definition: (define show-square (lambda () (place-image (square SIZE MODE (ran-clr)) ;; SIZE/2 PUTS THE PIN-HOLE OF THE SQUARE AT THE CENTER OF THE SCENE. (/ SIZE 2) ;; X-coordinate (/ SIZE 2) ;; Y-coordinate MTSQ) ) ) ; Post-function printfs: (printf "(show-square) => ~a~%" (show-square)) (printf "(show-square) => ~a~%" (show-square)) (printf "(show-square) => ~a~%" (show-square))