;=====
; CS 111 - Week 4 Lecture 1 - 2026-09-15
;=====

(require 2htdp/image)
(require 2htdp/universe)

;=====
; playing with boolean operations and, or, not

(and #true #t true)
(and #true #t true false #t #true)

(or #f #false false #true #f #f #f)

(not #true)
(not #false)

;=====
; 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 3 Lecture 2 posted examples
; (and edited to just include parts needed here)
;
; ...but then, during class, REFACTORED it
;    to add a named constant CENTER-X
;-----

(define WIDTH 400)
(define HEIGHT 200)

;-----
; ADDED this in Week 4 Lecture 1

(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.

;-----
; REFACTORED tests and function to use
;     new named constant CENTER-X

(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 from Week 3 Lecture 2
;           and modified during Week 4 Lecture 1)

;=====
; cond expression
;=====
; syntax:
;=====
;    (cond
;        [bool-expr1 result-expr1]
;        [bool-expr2 result-expr2]
;        [bool-expr3 result-expr3]
;        ...
;        [else result-expr-else]
;    )
;
;    *   the [bool-expr result-expr] parts can be called 
;        branches or clauses
;    *   the second expr in each clause can be of any type
;        (but it must have a value)
;
;=====
; semantics (meaning):
;=====
; *   evaluate each clause's boolean expression in order
;     until it finds one with the value #true --
;     that clause's 2nd expression becomes the value of the cond
;     expression
;
;     *   once a clause starting with a #true boolean expression
;         is found, the rest of the clauses are IGNORED, skipped!
;         *   at most one branch will be "taken", at most one
;             clause will have its 2nd expression evaluated
;
;     *   so the ORDER of the clauses matters!
;
;     *   if you include an [else ...] clause and it is reached,
;         else is always considered #true and the else clause's
;         2nd expression will be the value of the cond expression
;
;=====
; CS 111 Class Style:
;=====
; *   start each [bool-expr result-expr] clause in
;     a cond expression on its own line
;
; *   INDENT the start of each [boolean-expr result-expr]
;     clause in a cond expression under its (cond
;     by at least 2 spaces
;
; *   (for a long clause, indent its continuation line(s)
;     so it is clear which clause it is continuing)
;
; *   as always, ASK me if you have any questions about CS 111
;     class style!

;=====
; a silly example of a cond expression

(cond
  [(= 7 7) "oink"]
  [(> 1 3) "baa"]
  [(< 1 3) "moo"]
  [(> 1 3) "baa"]
)

;=====
; say I want a function to give a silly report
;     of a quantity of bananas...
; (kind of inspired by the song
;     "Yes, We Have No Bananas")

;=====
; signature: banana-report: number -> string
; purpose: expects a number that represents the
;     amount of bananas
;     and returns a silly report of the number of
;     bananas

;=====
; do you see that you should have at least one test for each
;     branch, and sometimes more, as we'll see later?

(check-expect (banana-report -13)
               "Yes, we have NO bananas!")

(check-expect (banana-report 0)
              "Yes, we have NO bananas!")

(check-expect (banana-report 1)
              "Yes, we have ONE banana!")

(check-expect (banana-report 100)
              "Yes, we have 100 bananas!")

(define (banana-report quantity-bananas)
    (cond
        [(<= quantity-bananas 0)
             "Yes, we have NO bananas!"]
        [(= quantity-bananas 1)
             "Yes, we have ONE banana!"]
        [(> quantity-bananas 1)
             (string-append "Yes, we have "
                            (number->string quantity-bananas)
                            " bananas!")]
    )
)

(banana-report -13)
(banana-report 0)
(banana-report 1)
(banana-report 100)

;=====
; another big-bang clause: stop-when
;
; stop-when expects a function that expects
;    the current world type and returns a
;    boolean
; each time big-bang's ticker ticks,
;    it calls stop-when's function with the
;    current world value, and if this function
;    returns true, big-bang ends

;-----
; fun fact: Racket has a function zero?
; zero? expects a number and returns whether
;    it is zero

"====="
"thanks to stop-when clause, this big-bang expression ends"
"    gracefully!"

(big-bang 100
  (on-tick sub1)
  (to-draw cyan-star-scene)
  (stop-when zero?))