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.







