Please send questions to
st10@humboldt.edu .
; CS 131 - Week 3 Lab - 8 am
(require 2htdp/universe)
(require 2htdp/image)
; today: adding the ability for keystrokes to affect our universes
; ...because handling keystrokes often involves using cond expressions
; so: the world doesn't have to just be a steadily-increasing counter;
; ...it COULD represent the current state of some "thing"
; (the current temperature, or the happiness of a virtual pet,
; or the current score of some game, or ...)
;
; (next week, we'll work toward worlds that are MORE than just 1 number...)
; in the universe,
; a key-handler function expects the current state of the world
; and something representing a key press,
; and it produces the state of the world that should result from that
; key press.
; strings are used to represent key presses in this universe;
; a string of a single letter represents typing that key,
; (and see documentation for other options, such as how up-arrow
; keys are represented, etc.)
; you will then give the name of this key-handler function to
; the function on-key when you call big-bang so that that function
; will be called on the current state of the world when you type
; a key;
; simple example:
; signature: affect-world: number string -> number
; purpose: expects the current state of the world and a keystroke,
; and if the keystroke is "u", it increases the world by 15,
; and of the keystroke is "d", is decreases the world by 15,
; and if it is any other key, the world is unchanged
; (note: string=? can compare 2 strings for equality;
; = can only compare numbers...)
(define U-STEP 15)
(define D-STEP 15)
(define (affect-world world-state a-key-stroke)
(cond
[(string=? a-key-stroke "u") (+ world-state U-STEP)]
[(string=? a-key-stroke "d") (- world-state D-STEP)]
[else world-state]
)
)
(check-expect (affect-world 25 "u") (+ 25 U-STEP))
(check-expect (affect-world 75 "d") (- 75 D-STEP))
(check-expect (affect-world 100 "x") 100)
(affect-world 25 "u")
(affect-world 75 "d")
(affect-world 100 "x")
; I also need a way to "draw" the world...
; my choice here is to take the world, and produce a scene that
; is that number turned into a text-image of font size 36
; and color red centered in a scene
; signature: draw-world-state: number -> scene
; purpose: expects a world state, and produces a scene that shows
; that world state centered in font size 36 and color red
(define WIDTH 100)
(define HEIGHT 100)
(define BACKDROP (empty-scene WIDTH HEIGHT))
(define (draw-world-state world-state)
(place-image (text (number->string world-state) 36 "red")
(/ WIDTH 2)
(/ HEIGHT 2)
BACKDROP)
)
(check-expect (draw-world-state 50)
(place-image (text (number->string 50) 36 "red")
(/ WIDTH 2)
(/ HEIGHT 2)
BACKDROP))
(check-expect (draw-world-state 100)
(place-image (text (number->string 100) 36 "red")
(/ WIDTH 2)
(/ HEIGHT 2)
BACKDROP))
(draw-world-state 50)
;-------------
; signature: get-1-bigger: number -> number
; purpose: expects a number, and produces the number
; that is 1 bigger
(define (get-1-bigger a-number)
(+ a-number 1)
)
; note -- this check-expect was written BEFORE get-1-bigger's
; body was filled in!
(check-expect (get-1-bigger 15) 16)
(get-1-bigger 45)
(big-bang 100
(on-tick get-1-bigger 1)
(on-draw draw-world-state)
(on-key affect-world))
; what if I would like big-bang to stop if/when the world reaches
; a certain state?
; I can have a stop-when expression in big-bang whose value
; is the name of a function, that expects the world and produces
; a boolean, and big-bang will stop if, when called, this
; function produces true
; I want big-bang to stop when the world becomes negative --
; I want a function that produces true when the world-state is
; negative
; signature: is-negative: number -> boolean
; purpose: expects a number, and produces whether it is negative.
(define (is-negative a-number)
(< a-number 0)
)
; need at least 3 tests: one for each of the 2 cases, and 1 for the boundary
; (in this case, 0)
(check-expect (is-negative -2) true)
(check-expect (is-negative 85) false)
(check-expect (is-negative 0) false)
(big-bang 20
(on-tick get-1-bigger 1)
(on-draw draw-world-state)
(on-key affect-world)
(stop-when is-negative))
; we might decide we'd like to call big-bang more than once,
; with different initial worlds;
; ...we can write a function to make this more convenient;
; because this starts up our world, when we specify an initial
; world, we'll call this function main
; (yes, sort of like main in C++ and Java)
; signature: main: number -> number
; purpose: expects a desired initial world state, and it calls
; big-bang with that as its initial world state, and then
; it produces the final world state that big-bang produces
; when it ends
(define (main init-world-state)
(big-bang init-world-state
(on-tick get-1-bigger 1)
(on-draw draw-world-state)
(on-key affect-world)
(stop-when is-negative))
)
(check-expect (main -3) -3)
; for a top-level function like main, that starts up a larger program,
; sometimes you can't write a complete set of check-expects...
(main 50)
(main -3)