;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-beginner-reader.ss" "lang")((modname 4a) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ; #lang htdp/bsl (require 2htdp/image) (require 2htdp/universe) ;; ----------------------------------------------------------------------------- ;; constants (define SIZE 600) (define CLOSE (/ SIZE 100)) (define BACKG (empty-scene SIZE SIZE)) (define FOOD (square 10 "solid" "green")) (define NOFOOD '()) (define TKY-RADIUS 5) (define TKY-STEP 10) (define PLAYER-COLOR "blue") (define AI-COLOR "brown") ;; ----------------------------------------------------------------------------- ;; data definitions (define-struct gobble (time ai player food)) (define-struct turkey (size color loc goal)) (define-struct food (x y)) ;; Gobbler = (make-gobble Number Turkey Turkey Food) ;; Turkey = (make-turkey Number String Posn OptPosn) ;; Food is one of NOFOOD or (make-food x y) ;; OptPosn is one of #false or Posn ;; INTERPRETATION (make-gobble t ai-turkey player-turkey f) represents a ;; game state with remaining clock ticks t, the two turkeys, and food f. ;; NOFOOD as food means one of the turkeys has eaten the food. ;; (make-turkey s c loc g) is a turkey of size s, color c, currently ;; located at loc and with goal g. ;; #false as a goal means the turkey has no goal and sits still, (define random-posn (make-posn (random SIZE) (random SIZE))) (define t-player (make-turkey TKY-RADIUS PLAYER-COLOR random-posn #false)) (define t-ai (make-turkey TKY-RADIUS AI-COLOR (make-posn 1 1) (make-posn 2 2))) (define food1 (make-food 10 20)) (define sample-world (make-gobble 10 t-ai t-player food1)) ;; ----------------------------------------------------------------------------- ;; PositiveNumber -> String ;; produce "you" if the player ate the food, ;; "ai" if the auto player ate it, ;; "tie" if the clock expired (define (main time) (winner (big-bang (create-world time) (to-draw xxx) (on-tick yyy) (on-mouse zzz) (stop-when www?)))) ;; Gobbler -> String ;; determine the winner by size or declare a tie (define (winner g) "tie") ;; ----------------------------------------------------------------------------- ;; PositiveNumber -> Gobbler ;; create a random world from the given amount of time ;; this test was formulated _after_ the fact to check for typos ;; it also demostrates that it is acceptable to use helper functions in tests (check-random (create-world 10) (make-gobble 10 (create-turkey AI-COLOR (make-posn (random SIZE) (random SIZE))) (create-turkey PLAYER-COLOR #false) (make-food (random SIZE) (random SIZE)))) (define (create-world t) (make-gobble t (create-turkey AI-COLOR (make-posn (random SIZE) (random SIZE))) (create-turkey PLAYER-COLOR #false) (make-food (random SIZE) (random SIZE)))) ;; String OptPosn -> Turkey ;; create a randomly placed turkey from the given name, color, and goal posn (check-random (create-turkey "b" #false) (make-turkey TKY-RADIUS "b" (make-posn (random SIZE) (random SIZE)) #false)) (define (create-turkey color goal) (make-turkey TKY-RADIUS color (make-posn (random SIZE) (random SIZE)) goal)) ;; ----------------------------------------------------------------------------- ;; *** place your wish list here *** ;; ----------------------------------------------------------------------------- ;; two helper functions that rely on domain knowledge from geometry ;; REVISED SIGNATURE ;; Posn Posn Number -> Posn ;; compute a Posn that is by delta closer to q than p ;; unless p is alreay delta-close to q (check-within (move-toward (make-posn 12 5) (make-posn 24 10) 13) (make-posn 24 10) .1) (check-within (move-toward (make-posn 12 5) (make-posn 24 10) 6.5) (make-posn 18 7.5) .1) ;; NEW TEST ;; MODIFIED October 2, per request by Antone on behalf of the class (check-within (move-toward (make-posn 12 5) (make-posn 24 10) 14) (make-posn 24 10) .1) (define (move-toward origin destination delta) (cond [(close? origin destination delta) destination] [else (posn+ origin (posn* (/ delta (size (posn- destination origin))) (posn- destination origin)))])) ;; Posn Posn Number -> Boolean ;; is the distance between p and q strictly less than delta (delta-close) (check-expect (close? (make-posn 10 10) (make-posn 10 9) 2.0) #true) (check-expect (close? (make-posn 10 10) (make-posn 10 9) 0.8) #false) (define (close? p q delta) (< (distance p q) delta)) ;; ----------------------------------------------------------------------------- ;; a library of positions (Cartesian points) and vectors (steps between points) ;; Vec is Posn. ;; INTEREPRATION When we call a Posn a Vec, we think of it 'directionally' ;; as in x over on the horizontal and y over on the verticla axis from here ;; Posn Posn -> Number ;; compute the distance between p and q (check-expect (distance (make-posn 3 4) (make-posn 0 0)) 5) (define (distance p q) (size (posn- p q))) ;; Vec -> Number ;; determine the size (length) of p (check-expect (size (make-posn 12 5)) 13) (define (size p) (sqrt (+ (sqr (posn-x p)) (sqr (posn-y p))))) ;; Number Vec -> Vec ;; multiply s componentwise with v (check-expect (posn* 2 (make-posn 1 3)) (make-posn 2 6)) (define (posn* s v) (make-posn (* s (posn-x v)) (* s (posn-y v)))) ;; Posn Posn -> Vec ;; subtract q from p componentwise to obtain a vector (check-expect (posn- (make-posn 3 2) (make-posn 3 8)) (make-posn 0 -6)) (define (posn- p q) (make-posn (- (posn-x p) (posn-x q)) (- (posn-y p) (posn-y q)))) ;; Posn Vec -> Posn ;; add q to p componentwise (check-expect (posn+ (make-posn 3 2) (make-posn 3 8)) (make-posn 6 10)) (define (posn+ p q) (make-posn (+ (posn-x p) (posn-x q)) (+ (posn-y p) (posn-y q))))