[plt-scheme] thanks, but help again
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