[plt-scheme] thanks, but help again

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Mar 30 18:51:45 EST 2004

Connor,

On Mar 29, 2004, at 9:27 PM, Connor Ferguson wrote:

> ;; hit-shot? : shot/f ufo -> boolean
> (define (hit-shot? shot/f ufo)
>   (cond
>     [ (boolean? shot/f) false]
>     [ else
>      (cond
>        [ (and (>= (+ (posn-x (ufo-nw ufo)) (ufo-len ufo))
>                  (posn-x (shot-posn shot/f)))
>              (>= (+ (posn-x (ufo-nw ufo)) (ufo-len ufo)
>                  (+ (posn-x (shot-posn shot/f)) (shot-l shot/f))
>              (<= (posn-x (ufo-nw ufo))
>                  (+ (posn-x (shot-posn shot/f)) (shot-l shot/f))
>              (>= (posn-y (ufo-nw ufo))
>                  (posn-y (shot-posn shot/f)))
>              (>= (posn-y (ufo-nw ufo))
>                  (+ (posn-y (shot-posn shot/f)) (shot-w shot/f)))) 
> true]
>        [ else false])]))
>
> I had been testing the program only by running it in the context of the
> game, but that is not something I should not do, so I formulated these
> tests.
>
> (hit-shot? (make-shot (make-posn 10 10) 2 5 'red)
>      (make-ufo (make-posn 10 10) 22 4 'green))
> = false
>
> (hit-shot? (make-shot (make-posn 30 30) 2 5 'red)
>                 (make-ufo (make-posn 10 10) 22 4 'green))
> = false
>
> (hit-shot? (make-shot (make-posn 100 100) 2 5 'red)
>                 (make-ufo (make-posn 10 10) 22 4 'green))
> = false

As you probably recall from last time, your problem came about because 
you didn't follow the design recipe and in particular, you didn't 
formulate tests. So this time you're in the same spot again. What you 
wrote up are *not* tests. You  seem to have run the function with 
certain inputs and you wrote down what the function produces. I can see 
that your first test should definitely produce true, not false. The 
shot is inside the ufo.

Next, as someone pointed out, your parentheses are all messed up. 
Fix'em. It's easy. Use Scheme | Indent All and DrScheme shows you were 
things are wrong.

Finally, step through that one test that you expect to be true and see 
why it's false. It's easy. I just did in 10 seconds, after fixing all 
the typos and parentheses:
>
> ;; hit-shot? : shot/f ufo -> boolean
> (define (hit-shot? shot/f ufo)
>   (cond
>     [ (boolean? shot/f) false]
>     [ else
>       (cond
>         [ (and (>= (+ (posn-x (ufo-nw ufo)) (ufo-len ufo))
>                    (posn-x (shot-posn shot/f)))
>                (>= (+ (posn-x (ufo-nw ufo)) (ufo-len ufo))
>                    (+ (posn-x (shot-posn shot/f)) (shot-l shot/f)))
>                (<= (posn-x (ufo-nw ufo))
>                    (+ (posn-x (shot-posn shot/f)) (shot-l shot/f)))
>                (>= (posn-y (ufo-nw ufo))
>                    (posn-y (shot-posn shot/f)))
>                (>= (posn-y (ufo-nw ufo))
>                    (+ (posn-y (shot-posn shot/f)) (shot-w shot/f))))
>           true]
>         [ else false])]))
>
>
> (hit-shot? (make-shot (make-posn 10 10) 2 5 'red)
>            (make-ufo (make-posn 10 10) 22 4 'green))

And when you do this you see that the last line produces false:

>> (>= (posn-y (ufo-nw ufo))
>>     (+ (posn-y (shot-posn shot/f)) (shot-w shot/f)))

And this line says that the Y coordinate of the UFO must be larger than 
the Y coordinate of the shot plus its WIDTH. Hmph, Y coordinates never 
have anything to do with WIDTH. Perhaps length will help:

>> (>= (posn-y (ufo-nw ufo))
>>     (+ (posn-y (shot-posn shot/f)) (shot-l shot/f)))

No still false. So let's see again. Perhaps you really want to say that 
the LOWER end of the UFO must include the SHOT. Ah, well, in that case, 
we really need to add the length of the UFO to its NW Y coordinate:

>> (>= (+ (posn-y (ufo-nw ufo)) (ufo-len ufo))
>>     (+ (posn-y (shot-posn shot/f)) (shot-w shot/f)))

Et volia`,  with a little bit of work, we got the structure of the 
program right, and with a little bit of guessing, we got the domain 
knowledge of the program right -- all working backwards from a small 
function and a small test case.

Design each function. Your program then has a chance of being right. 
Good luck -- Matthias



Posted on the users mailing list.