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

list processing
Frogger cont.

Due Oct.07 (Thu)05 (Tue); hardcopy not 'til Oct.12 (the next in-person lecture).

For this homework:

(These restrictions will all be lifted after this homework.)

Reading: §6.6, and §10.1–10.3.1.
(Additional recommended, but not required, background reading: all of Chpt.6, and §10.3. Additional, non-required, challenge-reading: § 10.5.)

All problems are to be written in Racket. Do not call any of the following functions:

Your name and the assignment-number must be in a comment at the start of the file All functions/data must include the appropriate steps1 of the-design-recipe.html. In particular, test cases alone might be worth 40-50% of the credit for a function. Have enough test cases to cover different corner cases; often 2–3 can suffice.

    part a

  1. Write the function count-bigs : real, list-of-real → natnum, which takes in a threshold and a list of numbers, and returns how many of them are larger than the threshold. To help you out, here are some test cases; no further ones are required. (The data-definition for list-of-number has already been given in lecture, so you don't need to repeat steps 1-3 of the design recipe for list-of-number.)
    Remember: We can't re-assign to variables, in functional programming. So we won't have a counter which we increment, like you might in your imperative-programming class. Instead, be sure to follow the design recipe, and after copying the template, think about the inventory-with-values (assuming we call our parameters “threshold” and “nums”): if we call count-bigs with the particular inputs (count-bigs 3 (cons 10 (cons 2 (cons 5 empty)))), what is…
    • threshold =     
    • nums =                                                                                                   
    • (first nums) =       
    • (rest nums) =                                                                   
    • (count-bigs threshold (rest nums)) =     
    Fill in each blank with a particular number, or list-of-numbers. Then, ask yourself: Starting with those pieces of info, how do I assemble them to get my desired result of 2?

    You don't need to include the above in your answer — it's just to remind you of what you do, for the “inventory-with-values” step of the design-recipe, #6. If you get stuck on any of the problems below, make sure you didn't skip this step; it's the one that can really make things click!

  2. Write the racket function map-sqr : list-of-number → list-of-number, which squares each number in a list; do not call map . To help you out, here are some test cases; no further ones are required.
    (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)))

Copy your hw04(structs) racket file to one that we'll use for this one. Add a very noticeable dividing-line (say, 80 ;s) between old code and the new. You will not need to turn in hardcopy of things before the dividing-line if they were in your hw04 solution or in the posted hw04-soln. Your hw05 may use any/all of the hw04-soln; of course, cite any code you use like this (including a URL), just as would do for any purpose, hw or not.

  1. For List-of-trucks,
    1. Give the datatype-definition for list-of-truck but no define-structs are necessary, since using the built-in cons suffices.
    2. Give at least 4 example values of this type. Your last example should contain at least four trucks; you may use this as the trucks in your game's initial world.
    3. Write the template for a list-of-truck processing function.
  2. Updating lists-of-objects.
    1. Write move-trucks : list-of-truck → list-of-truck , which returns a list where each truck has moved.
      Note: Your test cases can call our already-tested move-truck, which in turn suggests your code should! call it as well.
      Note: The code for this will follow directly from the template. Its return value happens to be a list; we have seen that both in lecture's tee (triple-every-even), and map-sqr above.
    2. 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. 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. Write the function
      ; keep-on-screen-trucks : list-of-trucks -> list-of-trucks
      ; Return a list containing only those trucks are not off-screen.
    4. 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, but I recommend: If a list's length falls below some threshold, then add (exactly one) new truck. (You can call length : list -> number; we wrote my-length in class, but length is also built-in.)

      Note that you can, if you want, create new trucks with some random attributes; see the built-in function random. … However, this makes unit-testing problematic, since you don't exactly know the expected result2. So for this problem, your tests might instead sometimes only check that the length of the result is as expected. (Of course, if you do know the exact expected result for certain inputs -- e.g. when the list is already longer than some threshold -- then do check for that full result.)

    5. Write trucks-collide-frog?, which determines whether a frog overlaps with any truck in a list-of-truck. Of course, you'll call last homework's truck-collide-frog? as a helper.

    6. Write function draw-trucks, which takes a list-of-items and, if needed, the fleet location and a background-image, and return the background image with the items overlaid on it. When creating the expected-output for your test cases, feel free to include the calls to draw-truck (singular), etc. from the previous homework. Creating the expected-result for a test for a list-of-length-2 will help you understand what your code needs to do.
  3. Worlds:
    1. Define a world structure which contains one frog, one prince(ss), and a list of trucks

      As usual for our data-definitions, make examples of the data (at least two).

    2. Give a template for world-processing functions.
    3. Write the function world-handle-key : world, key-event → world which returns a new world updated to handle the keypress. (Fairly easy — it mostly defers to frog-handle-key, and your test cases will largely crib from that.
    4. Write the function update-world : world → world which returns a new world one “tick” later. This will include calls to your move-X functions, as well as initiating diving and firing (which perhaps are only called when (say) the fleet's x-position is a multiple of 20). A single test-case might suffice for this, since your expected-result can(should) involve calls to functions that have already passed their tests.
    5. Write the function game-over? : world → boolean. This will be a thin wrapper over frog-collides-prince(ss) and/or trucks-collide-frog.
  4. Write draw-world, which has a slightly different signature: world -> image. This is the function that will proide the very first background-image that gets passed to other draw- functions.

All the above should have their tests, as well as signatures and (brief) purpose statements.

Only after all tests pass, add

(require 2htdp/universe)

(big-bang some-initial-world
          [on-key  world-handle-key]
          [on-tick update-world]
          [to-draw draw-world]
          [stop-when game-over?]
          )
and you can play your game. Btw, if you want to add sounds (which you have license to use), you can call play-sound-then from student-extras.rkt.


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 Here's how you could actually have unit-tests: Include the random-number-generator (“rng”) as one of the function's inputs. (Presumably it would be an optional-input, using a default system rng if not explicitly provided.) Then when testing, you can pass in a rng which you know is about to generate the number (say) 17, and thus you can predict the overall-function's result. In fact, you might pass in a dummy-rng which always generates 17. In testing/SE terminology, this is called “dependency injection” or “adding a seam”.

Or, in racket, see check-random!

     

logo for creative commons by-attribution license
This page licensed CC-BY 4.0 Ian Barland
Page last generated
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Rendered by Racket.