RU beehive logo ITEC dept promo banner
ITEC 380
2013fall
ibarland
aaray

homelecturesrecipeexamshwsD2Lbreeze (snow day)

hw03
Pacman; intro list handling
due Sep.30 (Mon) *and* Oct.02 (Wed) in class

Due Sep.30 (Mon) in class,

Note: #1-5 and #14 are due Mon. in class (D2L and hardcopy). The remainder are due Wed. (Wed.'s hardcopy doesn't need to include any of Monday's work, and vice versa — I actually prefer leaner printouts.)
Note: I will also accept hw03b up through the start of class Fri., at a 10%-late penalty.
with hard copy at the start of the following class. Your name and the assignment-number must be in a comment at the start of the file, and your hardcopy must be stapled. All functions/data must include the steps1 of the-design-recipe—the design recipe: final version. In particular, test cases alone might be worth half the credit for a function.

You may download and (require "student-extras.rkt"). This file includes ellipse/arc, as well as exporting let and let* for use in the student languages.

Reading:

The following questions relate to the beginning stages of designing a Pac-man-like game.

For this Homework, you'll submit two files: a .java and .rkt program file.

We start by representing the pacman, and writing a method involving them.
  1. (3pts) In both Java and Racket, develop a data-definition for a Pacman. For each field, give a short (two-to-three word) comment describing what it stands for, and its units. Natural units for screen-based games are pixels, and ticks (where a "tick" is an abstract amount of time, but it's conveninent to declare it as the amount of time between two frames).
    hint: To represent directions (or keypresses, or both), use the strings "left", "down", etc.; rather than symbols, and rather than "west", "south", etc.. This will play nicely with the keypress events of the 2htdp/universe library. This will be a union type.
    pro tip: Rather than keep track of both how wide-open the mouth currently is and whether it's opening or closing, I recommend being a little sneaky and just keep the pacman's “age”. Then you can use that number to generate how wide open the mouth should be, by taking the cosine of the age (or, call any other function2 which maps numbers to [0,1]).3
    1. Give a Java class to represent a pacman (non-static fields and a constructor only; your constructor should take as many arguments as there are fields). Note that no images are involved.
    2. Give a corresponding Racket define-struct statement.
      1. What is the signature of of the constructor which racket creates for you?
        (Recall from lect09-structs1.rkt, a function's signature is its name, along with the types of its parameters and its return type. For example, the signature of substring is substring : string, int, int → string and the signature of addition is + : number, number → number.)
      2. What is the name and signature of one of the pacman accessor functions which racket creates for you?
  2. (3pts) Make at least two different examples of the data; do this both in Java and in racket. (In Java, where all code must be inside a method, put these inside a static method void tests().)
  3. (3pts) Write the template for a pacman-processing function, in both racket and Java.
    (In Java, you'll have to comment out the template, since the “...” won't compile.)
  4. (5pts) In both racket and in Java: Write a function that converts a pacman's direction to an x-displacement (“dx”), and another to compute the y-displacement (“dy”).4 That is, heading left corresponds to an dx of +1 and a dy of 0, while heading north corresponds to a dx of 0 and a dy of -1. The function should take in just the direction, not an entire pacman.

    (You might have functions direction->dx and direction->dy, or you might have one function that returns both values wrapped in a posn structure / java.awt.Point, or a list-of-length-exactly-two (or array/vector of length 2). Whichever you choose should correspond to how you're representing the pacman's position — as two numbers, or a posn/Point, or a list-of-length-exactly-two.)

  5. (3pts) Create (in both racket and Java), a function move-pacman which takes in a pacman, and returns a pacman one "tick" of time later, ignoring any exterior factors like walls or ghosts or wrapping around the screen5. The Java and racket versions should work in the same way: returning a new object, rather than mutating any fields (Cf. turn-to-spades in the lecture notes).
  6. (3pts) In racket-only, write the function pacman->image, which returns the image for a pacman ready to be superimposed onto the game board. Hopefully you'll use6 the code for chomper from hw02, though feel free to modify it if you want. pacman->image will need to rotate the image appropriately.
  7. (5pts) In racket (only), write the function pacman-handle-key, which takes a pacman and a keypress (e.g. "a" or "left"), and returns a new pacman which has responded to that keypress.

    (For now, you can have the keypress take effect immediately, although in our final version we may “store” the keystroke until the next time the pacman can reaches an intersection.)

  8. (3pts) (racket-only) Write a function draw-world which takes in a pacman and returns an image: that pacman placed onto a(n otherwise blank) board. Only one test-case is required.
  9. All the above should have their tests, as well as signatures and (brief) purpose statements. Only after all tests pass, the following should work (in racket):

    (require 2htdp/universe)
    
    (big-bang some-initial-pacman
              [on-key  pacman-handle-key]
              [on-tick move-pacman]
              [to-draw draw-world])
    

  10. (6pts) To do collision detection, a suitable helper function would be to detect when two rectangles overlap (e.g. a rectangle and the pacman's bounding box).

    Write test cases and code for overlap?. (There are several reasonable ways to represent rectangles, but it helps if your representation aligns with the arguments needed for 2htdp/image's rectangle.)

    cool hint, from robotics: We can reduce this problem to a simpler one: checking if an expanded version of the first rectangle merely contains one particular point: the southeast corner of the second rectangle.
    For example: consider a 20x30 rectangle whose northwest corner is at (500,400) and a second rectangle which is 80x60. These two rectangles overlap exactly when the second rectangle's southeast corner is inside the (20+80)×(30+60) rectangle rooted at (500,400).
  11. (3 pts) Chpt.15, review question #9, the two forms of define. (If using 8ed: #5) (For each form, give (a) an example, (b) the general syntax 7, and (c) a one-sentence explanation of the semantics. That is, the same way cond was presented in lecture.) In your syntax-definition, you can refer to “Expr” (expression), “Id” (identifier), and “…” (0 or more of the preceding).
  12. (3pts) Chpt.15, review question #11. (If using 8ed: Why are car and cdr so named?)
  13. (3pts) Give a concise, 1-2 sentence paraphrasing of Paul Graham's “Blub paradox”.
    You can assume the premise (without re-stating it): Consider “a hypothetical language called Blub. Blub falls right in the middle of the abstractness continuum. It is not the most powerful language, but it is more powerful than Cobol or machine language.”.)
  14. (3pts) In that essay, what feature of Lisp does Paul Graham present as the one which makes it more powerful than most others?
  15. (3pts) Write the racket function count-bigs : number, (listof number) → natnum8, which takes in a threshold and a list of numbers, and returns how many of them are larger than the threshold.
      (check-expect (count-bigs 7 empty) 0)
      (check-expect (count-bigs 7 (cons 5 empty)) 0)
      (check-expect (count-bigs 7 (cons 7 empty)) 0)
      (check-expect (count-bigs 7 (cons 9 empty)) 1)
      (check-expect (count-bigs 7 (cons 3 (cons 7 empty))) 0)
      (check-expect (count-bigs 7 (cons 9 (cons 7 empty))) 1)
      (check-expect (count-bigs 7 (cons 3 (cons 9 empty))) 1)
      (check-expect (count-bigs 7 (cons 8 (cons 9 empty))) 2)
      (check-expect (count-bigs 7 (cons 3 (cons 7 (cons 8 (cons 2 empty))))) 1)
      
  16. (3pts) Write the racket function map-sqr : (listof number) → (listof number), which squares each number in a list:
      (check-expect (map-sqr empty)  empty)
      (check-expect (map-sqr (cons 7 empty))  (cons 49 empty))
      (check-expect (map-sqr (cons 9 (cons 7 empty)))  (cons 81 (cons 49 empty)))
      

1 Your final program doesn't need to include any "transitional" results from the template: For example, you don't need the stubbed-out version of a function from step 5. However, you should still have passed through this phase.      

2

; sawtooth : integer?, (and/c integer? positive?) -> real?
; Return a number between 0 and 1.
; As x increases, it's a rising-then-falling pattern: /\/\/\/\...
;    with a period of 2 * `period/2`.
;    (bug: this should allow real inputs, not just integer.)
;
(define (sawtooth x period/2)
  (/ (abs (- (modulo (- x period/2) (* 2 period/2)) period/2))
     period/2))

(check-expect (sawtooth   0 100)   0/100)
(check-expect (sawtooth   1 100)   1/100)
(check-expect (sawtooth   2 100)   2/100)
(check-expect (sawtooth  99 100)  99/100)
(check-expect (sawtooth 100 100) 100/100)
(check-expect (sawtooth 101 100)  99/100)
(check-expect (sawtooth 102 100)  98/100)
(check-expect (sawtooth 199 100)   1/100)
(check-expect (sawtooth 200 100)   0/100)
(check-expect (sawtooth 201 100)   1/100)
(check-expect (sawtooth 300 100) 100/100)
(check-expect (sawtooth 301 100)  99/100)
(check-expect (sawtooth 400 100)   0/100)
(check-expect (sawtooth 401 100)   1/100)
You're welcome. (If you use this code, site the source URL, of course.)      

3 Keeping track of age is definitely a hack, so that we can collapse two fields to one, but it feels relatively natural. It also suggests that we can use a pacman's age later on (for calculating score, or having the pacman evolve, or ...). Hopefully we won't want to, in the future, need to know whether the mouth is waxing or waning; if so we'll end up with uglier and less understandable code than the natural, straightforward two-field represention.      

4If you are already representing the direction via x- and y-offsets, then instead have a function that translates keypresses into the direction(s).      

5 You are encouraged to allow and test for pacman wrapping around the screen, but it won't be required; we can choose to later create walls which won't allow wrapping around. … On the other hand, it's only a few extra function calls and tests to support this feature.      

6In a real project, you'd use something like (require "hw02.rkt") to get that other function. However, we don't want to deal with having to submit more than one .rkt file to get running code, so go ahead and copy/paste your previous solution and tests into your hw03. Put this near the bottom of your hw03, and you're encourged to not print out the pages that contain already-graded code.      

7 Please distinguish between what words/punctation are required, and what gets replaced with a certain feature. For example, the syntax of an if-expression is (if Expr Expr Expr), where each of the Exprs can be any expression. Note that the “(if” is required punctuation/keyword and is something the programmer literally types in, whereas “Expr” (in different font/color) is something that the programmer replaces with some particular expression; they don't type E-x-p-r literally.      

8 I'll use “natnum” for “natural number” —0,1,2,….      

homelecturesrecipeexamshwsD2Lbreeze (snow day)


©2013, Ian Barland, Radford University
Last modified 2013.Oct.21 (Mon)
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Powered by PLT Scheme