RU beehive logo ITEC dept promo banner
ITEC 380
2009fall
ibarland

homeinfolecturesexamshwsarchive

hw04
handling lists
due Oct.07 (Wed) and Oct.12 (Mon)

On Oct.07 (Wed), turn in the code just for #1-#4, to be spot-checked. (The turn-in details shown after problem #4.) On Oct.12 (Mon), also turn in the entire assignment. Your name and the assignment-number must be in a comment at the start of the file.

The following problems deal with frogger. Follow all steps of the design recipe (from lect04c—recursive structs: and the design recipe and/or How to Design Programs. However, you do not need to provide test cases for functions which return images/scenes.

This of course builds on hw03; include your hw03 solution, but clearly mark1 where the hw04 portion of your solution begins. You will lose substantial credit if your hw04-specific functions repeat code which is already part of your hw03 solution; you should just call those functions, instead. (E.g. move-trucks had better call move-truck.)

For readability, I recommend putting all named-constants (including images) at the end of your file (as in hw03-soln.ss, for example).

  1. [2pts; 3-4 lines]
    Give a data definition for a list-of-trucks, examples of the data, and a template for any function which takes a list-of-trucks as input (Note that this template has to be in comments, since you don't even know what the return type would be.)
  2. [2pts; code is template + ~3 words]
    Write the function move-trucks (note the plural “s”), which maps move-truck onto a list of trucks:
    ; move-trucks: list-of-trucks -> list-of-trucks
    ; Return a list of all the trucks, where each has been moved.
    
    Test cases are required, of course.
  3. [2pts; code is template + ~3 words]
    Write the function trucks-handle-key, which takes in a list of trucks and a single key, and returns a new list of trucks where each truck has been updated by that key (as per truck-handle-key).
    Test cases are required, of course.
  4. [2pts; code is template + 2-4 words]
    Write the function draw-trucks, which takes in a list of trucks and a scene, and returns a new scene with every truck in the list overlayed onto it.
    No test cases are required for this problem, since the creating the expected image in advance is non-trivial.

Submit a printout the above four problems by themselves (without the rest of hw03, without the truck structs themselves, etc.), to be spot-checked. On WebCT, turn in the entire running code as hw04-check.


  1. [5pts] Go back and update your world struct so that it contains a list-of-trucks. Modify your examples of world structs, and the functions update-world, world-handle-key, and draw-world from the previous homework (including test cases2).
  2. [3pts] Write the function truck-off-screen?, which returns whether or not a given truck is entirely off the size of the image you use in draw-world. (Hint: call overlap? from hw03.)
    Note that this function neither consumes nor returns images; however it may use numbers (or better: named constants) which are also used inside draw-world.
  3. [3pts] Write the function
    ; remove-off-screen-trucks : list-of-trucks -> list-of-trucks
    ; Return a list containing only those trucks are not off-screen.
    
  4. [3pts] Write the function replenish-truck : list-of-trucks -> list-of-trucks, which sometimes adds new trucks to the given list. You can use whatever criterion you like:
  5. [3pts] Modify update-princess so that she teleports to a random location, after being in the same spot long enough.
  6. [5pts] Modify update-world so that it (a) moves trucks, then (b) removes trucks which are off the screen, and finally (c) replenishes trucks.
    Update test cases appropriately, as possible.
  7. [3pts] Write a structure for representing a frog, followed by several examples of the data.
    Hint: Don't include an image in the structure. Instead, just include some way to indicate which way the frog is facing. I suggest using "left", "up", etc.; since these strings also happen to be key-presses, this will make for some convenient3 for frog-handle-key.
  8. [5pts] Write the method frog-handle-key. Test cases required, of course.
    Hint: Use contains? from class to see if the key-press is one of the four valid directions.
  9. [3pts] Write the method draw-frog : frog scene -> scene.
    No test cases needed for this function.

    I recommend having a helper-function get-frog-image : string -> image which, given a string(keypress) for a frog's direction, returns an appropriate image. You can write test-cases for this helper function.

    To rotate or scale an image::

    You can open image-functions.ss in a new DrScheme tab, (clicking "Evaluate" once), and then just use the interactions window to cut/paste your original image and call functions like rotate90 or scale, cut/pasting the result back into your program.

    Or you can use photoshop. Or you can embed image-functions.ss in your hw, and call the rotate/scale functions every time you want to use them.

  10. [3pts] Add frogs to your world structure, updating world-handling functions as necessary.
  11. [3pts] Write truck-hitting-frog? : truck frog -> boolean.
    You can use overlap? on the truck's and frog's “bounding box”.4 Note that this function neither consumes nor returns images; test cases are required.
  12. [3pts] Write trucks-hitting-frog? : list-of-trucks frog -> boolean, which returns whether any truck in the list is hitting the given frog.
  13. [3pts] Write game-over? : world -> boolean.
    (The game is over when the frog is hit by a truck, or the frog has reached the princess.)
    Note that you can add the clause [stop-when game-over?] to the call to big-bang, to stop the simulation.
  14. [0pts] Bonus: adding sounds.

    The function play-sound will play a sound file. In order to use this function, your program must contain (require scheme/gui). (Some free sound files can be found at, say, mediacollege.com or partnersinrhyme.com; be sure to site your sources.)

    Playing a sound is a side-effect -- it changes the state of the world, but it doesn't return a value. When calling a function which has a side-effect, we often use begin. For example, the following expression evaluates to 14, but plays a sound as a side effect:

    (begin (play-sound "/Users/ibarland/Music/sounds/effects/beepbeep-01.wav")
           (+ 8 6))
    

    If you want to conditionally play a sound, you could write

    (begin (if some-condition
               (play-sound "/Users/ibarland/Music/sounds/effects/beepbeep-01.wav")
               'some-garbage-return-value)
           (+ 8 6))
    
    But this is a bit odd, having to provide an answer for the 'false' case, when we know that value is only going to get thrown away. Instead, you can use when:
    (begin (when some-condition
                 (play-sound "/Users/ibarland/Music/sounds/effects/beepbeep-01.wav"))
           (+ 8 6))
    

    You may only use begin and when in order to play sounds, in this assignment. For example, if you use a when expression as the body of, say, update-princess you'll get a function that runs, but doesn't always return a value5 (!). If you bump yourself up to advanced-student, you should understand when to (not) use when and begin.

(The last 7pts: for overall good code (well indented; not roundabout).)


1 DrScheme's Insert > Large letters… plays nicely with View > Show Program Contour.      

2

Between cleverly-chosen examples and cut/paste, it really isn't too difficult to create/revise test cases. Note that since more thorough tests for (say) update-trucks are provided elsewhere, the test cases for update-world don't need to test worlds with a wide variety of list-of-trucks; two or even one world is sufficient in this case.

In general, white-box test cases for world-handle-key would only focus on any interesting/odd interplay about how different list-of-trucks might interact with certain princesses. However, in our game, updating trucks and updating the princess is entirely orthogonal, so there is no interplay to worry about. One test case should suffice to test that we're doing the world accessing/constructing correctly.

     

3 Convenient, at the price of not being abstract: if we change our program to use (say) "a", "w", "d", "s" to control the frog, then our code would need more substantial revision.
In an even more general setting, there might be a dictionary (e.g. java.util.Map) which translates key-events to frog-directions; this would let a user set preferences for keyboard controls, would scale well to multi-users, working with non-keyboard controllers, etc.. But for now, we'll content ourselves with hard-coded keypresses.      

4 If you really want to do more sophisticated collision detection, you are welcome to. Presumably you'd use more sophisticated shapes than rectangles which would presumably correspond to the shape you're using in your draw- methods.      

5Technically, it returns a particular constant, "the void value". Note that no name is bound to this constant.      

homeinfolecturesexamshwsarchive


©2009, Ian Barland, Radford University
Last modified 2010.Jan.18 (Mon)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme