;===== ; CS 111 - Week 4 Lecture 2 - 2026-09-17 ;===== (require 2htdp/image) (require 2htdp/universe) ;===== ; REMINDER ;===== ; cond expression ; ; syntax: ; (cond ; [boolean-expr1 result-expr1] ; [boolean-expr2 result-expr2] ; [boolean-expr3 result-expr3] ; ... ; [else result-expr-else] ; ) ; ; semantics: ; * evaluate each clause's boolean expression in order ; until it finds one with the value #true -- ; that clause's 2nd/result expression becomes the value ; of the cond expression ;===== ; COPIED from Week 3 Lecture 2 posted examples ; (INCLUDING the signature, purpose, and tests! ;----- ; signature: cyan-star: number -> image ; purpose: expects the desired distance between ; the points of a star and returns an image ; of a cyan star of that size (check-expect (cyan-star 10) (star 10 "solid" "cyan")) (check-expect (cyan-star 4) (star 4 "solid" "cyan")) (define (cyan-star star-size) (star star-size "solid" "cyan") ) ;===== (END of part copied over from Week 3 Lecture 2) ;----- ; COPIED from Week 4 Lecture 1 posted examples ; (and edited to just include parts needed here) ;----- (define WIDTH 400) (define HEIGHT 200) (define CENTER-X (* 0.5 WIDTH)) (define BACKDROP (empty-scene WIDTH HEIGHT)) ;===== ; signature: cyan-star-scene: number -> scene ; purpose: expects a cyan star size and returns a scene ; of a cyan star of that size, centered. The scene will ; always be WIDTH x HEIGHT pixels. (check-expect (cyan-star-scene 20) (place-image (cyan-star 20) CENTER-X (* 0.5 HEIGHT) (empty-scene WIDTH HEIGHT))) (check-expect (cyan-star-scene 50) (place-image (cyan-star 50) CENTER-X (* 0.5 HEIGHT) (empty-scene WIDTH HEIGHT))) (define (cyan-star-scene star-size) (place-image (cyan-star star-size) CENTER-X (* 0.5 HEIGHT) (empty-scene WIDTH HEIGHT))) ;===== (END of part copied over and edited from Week 4 Lecture 1 ;===== ; remember: big-bang's stop-when clause ; expects the name of a function that ; expects the current world value's type and returns ; a boolean ; and when big-bang's ticker ticks, it calls the function ; from a stop-when clause with the current world value, ; and if that function returns #true, big-bang ends ; ; (get it? asking big-bang to stop when its function is #true...) ; "=====" "Thanks to stop-when clause with built-in Racket function " " zero?, this ends gracefully when world value reaches 0" "=====" (big-bang 100 (on-tick sub1) (to-draw cyan-star-scene) (stop-when zero?)) ;===== ; I'd like to be able to stop a big-bang expression involving ; cyan stars for too big OR too small values (define MAX-STAR-SIZE 200) ;===== ; recall the MATH notation for intervals: ; ( or ) means up to but NOT including that value ; [ or ] means INCLUDING that value ; ; so, for example: [3, 8) means all values between ; 3 and 8, *including* 3 but *not* including 8 ;===== ; SO: say I consider a "good" star size to be [1, MAX-STAR-SIZE] ; ; I could write a function that returns true if my ; proposed star size is "bad" ;===== ; signature: bad-star-size?: number -> boolean ; purpose: expects a star size, and returns #true if it ; is "bad" -- if it is outside the interval [1, MAX-STAR-SIZE] - ; and returns #false otherwise ;----- ; CS 111 Class Style: when your function is dealing with ; numeric intervals, need a test for each interval, ; PLUS a test for each BOUNDARY value between intervals ;----- ; SO, since this interval divides a number line into 3 regions, or ; intervals, I should have at least 1 test per region, ; PLUS an additional test for each boundary between regions -- ; ; so, we need at least FIVE tests here (3 intervals, and 2 boundaries ; in-between): (check-expect (bad-star-size? -1) #true) (check-expect (bad-star-size? 1) #false) (check-expect (bad-star-size? 7) #false) (check-expect (bad-star-size? MAX-STAR-SIZE) #false) (check-expect (bad-star-size? (+ 10 MAX-STAR-SIZE)) #true) ;----- ; (just for your reference, I am including the ; versions we refactored from during class -- ; that is not required!) (define (bad-star-size? star-size) ; ; version 1 - 3-branch version ; (cond ; [(< star-size 1) #true] ; [(> star-size MAX-STAR-SIZE) #true] ; [else #false] ; ) ; ; refactored version 2 - ; ; combining the #true cases into one branch using or ; (cond ; [(or (< star-size 1) ; (> star-size MAX-STAR-SIZE)) ; #true] ; [else #false] ; ) ; refactored version 3 - realizing a single boolean expression ; can work here for this boolean function (or (< star-size 1) (> star-size MAX-STAR-SIZE)) ) (bad-star-size? (+ MAX-STAR-SIZE 167)) "=====" "thanks to stop-when clause using our new function" " bad-star-size?, both of these big-bang calls end" " gracefully!" "=====" (big-bang 100 (on-tick sub1) (to-draw cyan-star-scene) (stop-when bad-star-size?)) (big-bang 50 (on-tick add1) (to-draw cyan-star-scene) (stop-when bad-star-size?)) ;====== ; it's penguin time! ;===== ; some useful named constants ;---- ; these images were originally from ; http://wallofgame.com/free-online-games/arcade/231/Parachute_Penguin_Shootout.html): (define FLOATING-PENGUIN (bitmap/url "https://nrs-projects.humboldt.edu/~st10/f26cs111/floating-penguin.png")) (define LANDED-PENGUIN (bitmap/url "https://nrs-projects.humboldt.edu/~st10/f26cs111/landed-penguin.png")) FLOATING-PENGUIN LANDED-PENGUIN (define PENG-SC-WIDTH 300) (define PENG-SC-HEIGHT 450) (define PENG-SC-BACKGD (empty-scene PENG-SC-WIDTH PENG-SC-HEIGHT)) (define PENG-CTR-X (/ PENG-SC-WIDTH 2)) ;===== ; oh -- want the penguin to "land" when its feet roughly ; reach the "ground" -- ; BUT place-image tends to center the image at the (x, y) coordinates ; specified (although there are also ways to change ; what is considered its "center" -- see put-pinhole ; in the 2htdp/image documentation) ; so -- a bigger y is further down in a scene coordinate system; ; I want to switch to a landed penguin before PENG-SC-HEIGHT; ; ...so, for a y value smaller than PENG-SC-HEIGHT -- ; ...how much smaller? Half of the landed penguin's height smaller; ; ; SO could subtract half the landed penguin's height ; from PENG-SC-HEIGHT to get a better landing height; (define LANDING-HEIGHT (- PENG-SC-HEIGHT (/ (image-height LANDED-PENGUIN) 2))) ;===== ; signature: draw-penguin-scene: number -> scene ; purpose: expects a penguin's y coordinate, ; and if it is less than the LANDING-HEIGHT, ; it returns a scene of a floating penguin centered ; at that y coordinate; ; otheriwse, it returns a scene of a now-landed penguin ; on the "ground" ;----- ; for this function, I want at least 3 tests: ; one that results in a floating penguin scene, ; one that results in a landed penguin scene, ; and one for the boundary between these two world-num ranges ; (more tests are fine!) (check-expect (draw-penguin-scene 10) (place-image FLOATING-PENGUIN PENG-CTR-X 10 PENG-SC-BACKGD)) (check-expect (draw-penguin-scene LANDING-HEIGHT) (place-image LANDED-PENGUIN PENG-CTR-X LANDING-HEIGHT PENG-SC-BACKGD)) (check-expect (draw-penguin-scene (+ 100 LANDING-HEIGHT)) (place-image LANDED-PENGUIN PENG-CTR-X LANDING-HEIGHT PENG-SC-BACKGD)) (define (draw-penguin-scene y-coord) (cond [(< y-coord LANDING-HEIGHT) (place-image FLOATING-PENGUIN PENG-CTR-X y-coord PENG-SC-BACKGD)] [else (place-image LANDED-PENGUIN PENG-CTR-X LANDING-HEIGHT PENG-SC-BACKGD)] ) ) "=====" "CLOSE World window when you are ready to go on --" " this big-bang expression continues to run until then!" "=====" (big-bang 0 (on-tick add1) (to-draw draw-penguin-scene)) ;===== ; draw-penguin-scene involved interval-style data; ; here's an example involving enumeration-style data ;===== ; enumeration-style data - a type of data that is a ; relatively small number of discrete, specific cases -- ; * a traffic light's colors of red, or yellow, or green ; * 4 arrow keys of up, down, left, right ; * etc. ;===== ; a silly example using enumeration data ;----- ; based on Sandra Boynton's "Moo, Baa, La La La" ;===== ; signature: next-sound: string -> string ; purpose: expects an animal sound as a string, ; and returns the next sequential animal sound ; based on the beginning of Sandra Boynton's ; "Moo, Baa, La La La" as follows: ; * for "moo", it returns "baa" ; * for "baa", it returns "la la la" ; * for "la la la", it returns "oink" ; * for "oink", it returns "moo" ; * for any other sound, it returns "???" ;----- ; I need at least 5 tests here -- ; one for each of the 4 possible sounds, ; and because I specified what to do for a "bad" sound, ; I also need to test for that (check-expect (next-sound "moo") "baa") (check-expect (next-sound "baa") "la la la") (check-expect (next-sound "la la la") "oink") (check-expect (next-sound "oink") "moo") (check-expect (next-sound "bark") "???") (define (next-sound farm-sound) (cond [(string=? "moo" farm-sound) "baa"] [(string=? "baa" farm-sound) "la la la"] [(string=? "la la la" farm-sound) "oink"] [(string=? "oink" farm-sound) "moo"] [else "???"] ) ) (next-sound "moo") (next-sound "fred")