;=====
; CS 111 - Week 7 Lecture 1 - 2026-10-06
;
; (because Exam 1 Review took the entire class,
;     posting a completed version of add-shape
;     created AFTER class)

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

;=====
; copied from Week 6 Lecture 2 posted examples,
;     then edited a bit

;-----
; I'd like to have a big-bang world that is
;     a list of images...
;
; And: I'd like those images be displayed randomly
;     in a scene each time big-bang draws its
;     world...

;-----
; some useful named constants

(define SC-WIDTH 300)
(define SC-HEIGHT 200)
(define BACKGRD (empty-scene SC-WIDTH SC-HEIGHT))

;-----
; making a function to use with on-tick to return
;     the current world unchanged when big-bang
;     calls it after each ticker tick

;-----
; signature: return-current: Anything -> Anything
; purpose: expects any expression with a value,
;     and returns its value

(check-expect (return-current 15) 15)
(check-expect (return-current #true) #true)

(define (return-current a-val)
   a-val
)

;-----
; to-draw in this case needs a function that'll
;    create a scene from a list of images,
;    placing each randomly into a scene

;-----
; signature: draw-images-randomly: list -> scene
; purpose: expects a list of images, and returns a
;    scene with those images placed at random
;    locations

;-----
; need at least two tests, and for a function expecting
;    a list of uncertain size,
;    one of those tests needs to be for an empty list!

(check-expect (draw-images-randomly empty)
              BACKGRD)

;-----
; for more-convenient testing...

(define SHAPE-TRIO
    (cons (circle 30 "solid" "purple")
          (cons (triangle 35 "outline" "darkgreen")
                (cons (square 50 "solid" "gray")
                      empty))))

SHAPE-TRIO

(check-random (draw-images-randomly SHAPE-TRIO)
      (place-image (first SHAPE-TRIO)
                   (random SC-WIDTH)
                   (random SC-HEIGHT)
                   (place-image
                      (second SHAPE-TRIO)
                      (random SC-WIDTH)
                      (random SC-HEIGHT)
                      (place-image
                          (third SHAPE-TRIO)
                          (random SC-WIDTH)
                          (random SC-HEIGHT)
                          BACKGRD))))
                   
(define (draw-images-randomly image-list)
     (cond
         [(empty? image-list) BACKGRD]
         [else (place-image
                  (first image-list)
                  (random SC-WIDTH)
                  (random SC-HEIGHT)
                  (draw-images-randomly (rest image-list)))]
     )
)

(draw-images-randomly SHAPE-TRIO)

"====="
"non-interactive version -- "
"    CLOSE the big-bang World window to continue!"
"====="

(big-bang SHAPE-TRIO
   (on-tick return-current 0.5)
   (to-draw draw-images-randomly))

; end of part copied and edited from
;     Week 6 Lecture 2 posted
;=====

;=====
; In Week 6 Lecture 2, STARTED a function for big-bang's
;     on-key clause,
;     to allow us to ADD an image to a given list of images based
;     on a given keystroke
; Now FINISHING it!

;=====
; signature: add-shape: list string -> list
; purpose: expects a list of images and a shape key,
;    either c or t or s, and returns a new list
;    with a new first shape added to the given list
;    as follows:
;    for "c", 20-pixel solid randomly-colored circle
;    for "t", 25-pixel solid randomly-colored triangle
;    for "s", 25-pixel solid randomly-colored star
;    and adds nothing if given any other string

;=====
; NEXT: complete at least 4 tests for this function
;     involving enumeration data
; *   one for "c"
; *   one for "t"
; *   one for "s"
; *   one for a string other than those

;-----
; for tests, it is good to use DIFFERENT arguments
;     in different tests --
; that is, don't use the SAME list of images in the tests

(check-random (add-shape SHAPE-TRIO "moo") SHAPE-TRIO)

(check-random (add-shape empty "c")
              (cons (circle 20 "solid" (make-color (random 256)
                                                   (random 256)
                                                   (random 256)))
                    empty))

(check-random 
    (add-shape (list (square 20 "solid" "purple")
                     (rectangle 10 10 "outline" "black")) "t")
               (cons (triangle 25 "solid" (make-color (random 256)
                                                      (random 256)
                                                      (random 256)))
                     (list (square 20 "solid" "purple")
                           (rectangle 10 10 "outline" "black"))))

(check-random (add-shape (cons (square 100 "outline" "red") empty) "s")
              (cons (star 25 "solid" (make-color (random 256)
                                                 (random 256)
                                                 (random 256))) 
                    (cons (square 100 "outline" "red") empty)))

;-----
; after writing the tests, we can paste in a suitable body template --
;
; oh, but which? are there "dueling" templates here?
;     (the one of enumeration data? the one for a function "walking through"
;     a list?)
;
; BUT -- we are NOT walking through the list here -- we are just
;     ADDING to its beginning -- BASED on the enumeration data;
;
; so, enumeration template "wins", then!

(define (add-shape image-list shape-key)
;   could START with a branch for each enumeration instance,
;       plus an else for any other string;
;
;   (cond
;       [... ...]
;       [... ...]
;       [... ...]
;       [else ...]
;   )
;
;   and then fill it in:

    (cond
        [(string=? shape-key "c")
             (cons (circle 20 "solid" (make-color (random 256)
                                                  (random 256)                
                                                  (random 256)))
                   image-list)]
        
        [(string=? shape-key "t")
             (cons (triangle 25 "solid" (make-color (random 256)
                                                    (random 256)                
                                                    (random 256)))
                   image-list)]
        
        [(string=? shape-key "s")
             (cons (star 25 "solid" (make-color (random 256)
                                                (random 256)                
                                                (random 256)))
                   image-list)]
        
        [else image-list]
    )
)

"====="
"INTERACTIVE version -- "
"    type c and/or t and/or s and see "
"    what happens!"
""
"    CLOSE the big-bang World window to continue!"
"====="

(big-bang SHAPE-TRIO
          (on-tick return-current 0.5)
          (on-draw draw-images-randomly)
          (on-key add-shape))