; CS 111 - Week 3 Lecture 2 - 2016-09-08

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

;==========
; reminder:
;    place-image can add one image to a given scene
;    and return a new scene including that image;

;    to get multiple images in a scene,
;    you can call place-image with a
;    nested call to place-image, and nest as
;    deeply as desired...

; let's use these as a standard width and height
;    for today's scenes

(define WIDTH 400)
(define HEIGHT 200)

;--------
; this compound expression results in a scene containing
;     three images...

(place-image (circle 10 "outline" "black")
             50
             50
             (place-image (triangle 20 "solid" "orange")
                          325
                          175
                          (place-image
                              (star 20 "solid" "red")
                              225
                              125
                              (empty-scene WIDTH HEIGHT))))

; I can give this constant-3-image-scene
;    a name for convenient reuse if I would
;    like;
; I think I'll make this my backdrop for today

(define BACKDROP
        (place-image
            (circle 10 "outline" "black")
            50
            50
            (place-image (triangle 20 "solid" "orange")
                         325
                         175
                         (place-image
                              (star 20 "solid" "red")
                              225
                              125
                              (empty-scene WIDTH HEIGHT))))
)
BACKDROP

;========
; say I decide I want a function that expects a star-size,
;    and returns a scene of a centered purple star of
;    that size?
; (in a scene of size WIDTH and HEIGHT,
;    that already has a little circle, star, and triangle in it)(

;============
; gee, my older function purple-star would be
;    useful here!
; (pasting in its signature, purpose,
;     tests/check-expects, and definition)

; signature: purple-star: number -> image
; purpose: expects the desire distance in pixels
;    between points of a 5-pointed star,
;    and returns a solid purple star image
;    of that size

(check-expect (purple-star 15)
              (star 15 "solid" "purple"))
(check-expect (purple-star 30)
              (star 30 "solid" "purple"))

(define (purple-star size)
    (star size "solid" "purple")
)

;========
;  now - back to writing a function that returns a scene
;      with a purple star of a specified size...

;--------
; signature: purple-star-scene: number -> scene
; purpose: expects a star-size,
;    and returns a scene of a centered purple star of
;    that size
; (in a scene of size WIDTH and HEIGHT,
;    that already has a little circle, star, and triangle in it)

;(define (purple-star-scene star-size)
;    ...
;)

(check-expect (purple-star-scene 25)
              (place-image
                  (purple-star 25)
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  BACKDROP))
(check-expect (purple-star-scene 160)
              (place-image
                  (purple-star 160)
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  BACKDROP))

(define (purple-star-scene star-size)
    (place-image (purple-star star-size)
                 (/ WIDTH 2)
                 (/ HEIGHT 2)
                 BACKDROP)
)

(purple-star-scene 25)
(purple-star-scene 160)

;=========
; intro to big-bang

; big-bang is a function in the 2htdp/universe teachpack
;
; when you start it, it starts a ticker ticking,
; (by default about 28 times per second)
;
; big-bang EXPECTS an initial world value,
;    which can be of any type you choose
;    it also expects one or more CLAUSES, to control
;    what happens to the world as the ticker ticks

; how do you write a big-bang clause?
;
; (desired-clause-type funct-name)
;
; one of big-bang's clauses is:
;    to-draw
;    ...tell big-bang HOW to draw the world!
;    you give the to-draw clause a function
;    that EXPECTS a value of the world's type
;    and RETURNS a scene depicting that world value

;    ...and big-bang now calls THAT function with
;    the CURRENT world at every ticker tick
;    (and displays it)
;
;    when you close the depicted world window
;    or otherwise end big-bang, it returns the
;    value of the world at that point

; my world here is a number,
;    and I want to display it as a scene with a purple
;    star whose size is the current world value 

"THIS call to big-bang draws an UNCHANGING purple star scene"

(big-bang 25
          (to-draw purple-star-scene)
)

;========
; um, that is not dynamic!
; fortunately, there's a clause that asks big-bang
;    to CHANGE the world at each ticker-tick

; that's the on-tick clause --
; it expects the name of a function that expects the
;    current world, and returns the world as it should
;    change because the ticker ticked
; (and then on-draw causes the new world to be drawn
;    because it calls its draw function on the new
;    world value)

;--------
; BSL Racket happens to have a function add1

; signature: add1: number -> number
; purpose: expects a number, and returns the number
;    one larger than the given number

(add1 27)

; add1 can be the function given to on-tick!

"THIS call to big-bang has a GROWING purple star scene"

(big-bang 25
          (to-draw purple-star-scene)
          (on-tick add1))

;--------
; there's a function sub1 also...

; signature: sub1: number -> number
; purpose: expects a number, and returns the number
;    one smaller than the given number

"THIS call to big-bang has a SHRINKING purple star scene"

(big-bang 200
          (to-draw purple-star-scene)
          (on-tick sub1))

;========
; what if you would like a purple star that moves ACROSS the
;     screen?
; ...what if you give to-draw a function that expects a
;     desired x-coordinate, and it centers a purple star at
;     that x-coordinate?

;--------
; signature: purple-star-scene-2: number -> scene
; purpose: expects a desired x coordinate,
;    and returns a scene of a PURPLE-STAR-SIZE'd purple star 
;    centered at that x coordinate (and halfway down)
; (in a scene of size WIDTH and HEIGHT,
;    that already has a little circle, star, and triangle in it)

(define PURPLE-STAR-SIZE 50)

;(define (purple-star-scene-2 x-coord)
;    ...
;)

(check-expect (purple-star-scene-2 25)
              (place-image
                  (purple-star PURPLE-STAR-SIZE)
                  25
                  (/ HEIGHT 2)
                  BACKDROP))
(check-expect (purple-star-scene-2 160)
              (place-image
                  (purple-star PURPLE-STAR-SIZE)
                  160
                  (/ HEIGHT 2)
                  BACKDROP))

(define (purple-star-scene-2 x-coord)
    (place-image (purple-star PURPLE-STAR-SIZE)
                 x-coord
                 (/ HEIGHT 2)
                 BACKDROP)
)

(purple-star-scene-2 25)
(purple-star-scene-2 160)

"THIS call to big-bang has a purple star moving left-to-right til gone"

(big-bang -15
          (to-draw purple-star-scene-2)
          (on-tick add1))

;========
; there are SEVERAL ways to keep the star in the
;   scene, or keep its size in a range, etc.

; the conditional expression next week will be
;    one way --
; another is using an odd little operation called
;    modulo, which gives the remainder from
;    integer division of its arguments

(modulo 256 5) ; what is the integer remainder
               ; of dividing 256 by 5
(modulo 257 5)
(modulo 258 5)
(modulo 259 5)
(modulo 260 5)
(modulo 261 5)

; NOTICE -- if you divide ANY integer by 5, the integer remainder
;    has to be 0, 1, 2, 3, or 4, right?
; And -- if you divide ANY integer by 10, the integer remainder
;    has to be 0, 1, 2, 3, 4, ..., 9, right?
; AND -- if you divide ANY integer by WIDTH, the integer remainder
;    has to be in [0, (WIDTH-1)] -- gee, within our scene!

;--------
; modulo is LOVELY for making sure a value stays WITHIN a
;     given range!

; let's use modulo to make sure purple star going across always
;     stays "in" the scene...!

;--------
; signature: purple-star-scene-3: number -> scene
; purpose: expects a desired world value,
;    and returns a scene of a PURPLE-STAR-SIZE'd purple star 
;    centered at the x coordinate of (modulo given-value WIDTH)
;    (and halfway down)
; (in a scene of size WIDTH and HEIGHT,
;    that already has a little circle, star, and triangle in it)

;(define (purple-star-scene-3 world-val)
;    ...
;)

(check-expect (purple-star-scene-3 25)
              (place-image
                  (purple-star PURPLE-STAR-SIZE)
                  25
                  (/ HEIGHT 2)
                  BACKDROP))
(check-expect (purple-star-scene-3 (+ WIDTH 10))
              (place-image
                  (purple-star PURPLE-STAR-SIZE)
                  10
                  (/ HEIGHT 2)
                  BACKDROP))

; ADDING a test to see how behaves at "boundary" value of
;    WIDTH itself! ... star should be drawn at x coord of 0, right?

(check-expect (purple-star-scene-3 WIDTH)
              (place-image
                  (purple-star PURPLE-STAR-SIZE)
                  0
                  (/ HEIGHT 2)
                  BACKDROP))

(define (purple-star-scene-3 world-val)
    (place-image (purple-star PURPLE-STAR-SIZE)
                 (modulo world-val WIDTH)
                 (/ HEIGHT 2)
                 BACKDROP)
)

(purple-star-scene-3 25)
(purple-star-scene-3 (+ WIDTH 10))

"THIS call to big-bang has a purple star moving left-to-right repeatedly"

(big-bang -15
          (to-draw purple-star-scene-3)
          (on-tick add1))