So I'm learning Scheme with HtDP. While answering the questions, I write this beautiful piece of code:
(define (main w0)
(big-bang w0
(on-tick ticking)
(on-key fire-key)
(to-draw to-render)))
(define HEIGHT 100)
(define WIDTH 80)
(define TURRET-X-POS (/ WIDTH 2))
(define BKGRND (empty-scene WIDTH HEIGHT))
(define SHOT-IMG (triangle 4 "solid" "red"))
(define (to-render w0)
(cond
[(empty? w0) BKGRND]
[else (place-image SHOT-IMG TURRET-X-POS (first w0) (to-render (rest w0)))]))
(define (fire-key w0 ke)
(cond
[(key=? ke " ") (cons HEIGHT w0)]
[else w0]))
(define (ticking w0)
(cond
[(empty? w0) empty]
[(empty? (only-inbound-shots w0)) empty]
[else (cons (sub1 (first (only-inbound-shots w0)))
(ticking (rest (only-inbound-shots w0))))]))
(define (only-inbound-shots w0)
(cond
[(< (first w0) -4) (rest w0)]
[else w0]))
The guys over at Stack Overflow barfed something fierce! I was rather ashamed. The great offender was the "ticking" function.
A few hours later, 5 cracked keys, and the loss of a cup of blood, I ended up with this:
(define HEIGHT 100) ;height of scene
(define WIDTH 80) ;width of scene
(define TURRET-X-POS (/ WIDTH 2)) ;position of turret, ie. where shot's x-coordinate
(define BKGRND (empty-scene WIDTH HEIGHT)) ; scene itself
(define SHOT-IMG (triangle 4 "solid" "red")) ;image representing the shot
(define Y-BOUNDARY -4) ;y-coordinate where shot is no longer visible in scene
;List-of-numbers -> List-of-numbers
;renders all shots fired
(define (to-render w0)
(cond
[(empty? w0) BKGRND]
[else (place-image SHOT-IMG TURRET-X-POS (first w0) (to-render (rest w0)))]))
;List-of-numbers, key event -> List-of-numbers
;only allows the space bar to fire a shot
;one space bar event produces one shot
(define (fire-key w0 ke)
(cond
[(key=? ke " ") (cons HEIGHT w0)]
[else w0]))
;List-of-numbers -> List-of-numbers
;during each clock tick, the y-coordinate each of the shot in List-of-numbers is updated
;each y-coordinate decreases by -1
(define (ticking w0)
(cond
[(empty? w0) w0]
[else (only-inbound-shots (update-shots w0) Y-BOUNDARY)]))
;List-of-numbers -> List-of-numbers
;does the actual updating of the shots in List-of-numbers
;each shot's value is decreased by -1
(define (update-shots w0)
(cond
[(empty? w0) w0]
[else (cons (sub1 (first w0)) (update-shots (rest w0)))]))
;List-of-numbers -> List-of-numbers
;checks to see if the first shot in the List-of-numbers has gone past the Y-BOUNDARY
;if so then remove shot from the List-of-numbers and return the rest of the List
;otherwise return the List without change
(define (only-inbound-shots w0 y-boundary)
(cond
[(empty? w0) w0]
[(< (first w0) y-boundary) (rest w0)]
[else w0]))
;List-of-numbers -> List-of-numbers
;creates the world of shots
;seed value is empty, additional values created by space bar
(define (main w0)
(big-bang w0
(on-tick ticking)
(on-key fire-key)
(to-draw to-render)))
Actually I'm very happy with this code. So unfortunately, this Coding Horror has a happy ending.
