[plt-scheme] thanks, but help again

From: Connor Ferguson (psfreak at linkline.com)
Date: Tue Mar 30 20:09:22 EST 2004

What I ran through the program were what I thought were tests. Aren't tests
just thinking up an example input for the program, figuring out what the
expected result should be, running the program and then comparing the
expected result with the actual output of the program? Please tell me if no,
but this is what I understood from the book. If I didn't read it right,
correct me please.

What Matthias said worked and the shot registered as hit when it passed
through the UFO. However, if the shot missed the UFO and the UFO moved in
line with where the shot was, it registered as hit. I¹m stumped on this one.
Whenever I get it to not register as hit when the shot has passed through
and the UFO has come back into its path like above, it won¹t hit when the
shot actually passes through. I¹m really getting frustrated with this. Here
is the function that registers as hit when it should, but also when the shot
has already passed.

;; 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)) (ufo-len ufo))
                 (+ (posn-y (shot-posn shot/f)) (shot-w shot/f)))) true]
       [ else false])]))

I also tried the code Zhu suggested, but that produced the opposite. Nothing
registered as hit with the shot. I'm getting very frustrated with this
program!!

-Connor


on 3/30/04 3:51 PM, Matthias Felleisen at matthias at ccs.neu.edu wrote:

> 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.