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

list processing
Galaga II

Part A: Problems 1-4 and 7,8 due Oct.11 (Fri) 23:59 on D2L (no hardcopy).
Part B: The remainder due Oct.14 (Mon) at start of class; submit all problems (incl. part A) on D2L, and hardcopy.

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

  1. (5pts) 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. (5pts) 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-soln2. Please include part A (problems 1,2) in your part B hardcopy.

  1. (5pts) List-of-aliens:
    1. Give the data-definition for list-of-alien 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 six aliens; you may use this as the aliens in your game's initial world.
    3. Write the template for a list-of-alien processing function.
  2. (5pts) Write draw-aliens : list-of-alien, image → image, similar to the draw-* functions from hw04.html.
    hint: When creating the expected-output for your test cases, feel free to call draw-alien.
  3. (10pts) Write move-alien : alien → alien, and then use that as a helper for move-aliens : list-of-alien → list-of-alien.
  4. (5pts) Write draw-missiles and move-missiles, similarly.
  5. Worlds:
    1. (2pts) Define a “world” structure which contains one ship, a list of missiles, list of aliens, and a “fleet direction” (whether the aliens are currently marching to the right, or to the left).

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

    2. Give a template for world-processing functions.

    3. (3pts) Write the function update-world : world → world which returns a new world one “tick” later. For the moment, update-world can ignore collisions with missiles, and it can leave the fleet-direction unchanged. We’ll fix those below.
  6. (2pts) Write the function world-handle-key : world, keypress → world which returns a new world updated to handle the keypress. (Should be easy -- mostly defers to ship-handle-key, and your test cases will largely crib from that. Firing, however, will be part of this function.)
  7. (3pts) Write the function draw-world : world -> image, which draws the world onto a blank background.
    hint: Call draw-ship with an empty-scene for the background; call draw-missile passing it the result of draw-ship as the second argument. In turn, use that result as the 2nd arg to draw-aliens.

Collisions

We'll count a collision as overlapping bounding boxes. Here is a provided with overlap.rkt, which determines if two rectangles overlap (given their centers and sizes).

  1. (5pts) Write alien-collide-missile?, which determines whether a single alien overlaps with a single missile. Have two test cases (this is reasonably sufficient, given that you already have a fully-tested overlap?).
  2. (5pts) Write aliens-remaining : list-of-alien, missile → list-of-alien which returns all aliens in the given list which are not colliding with the given missile.
    hint: We previously saw, when counting certain items in a list — where we either added 1 or left our value unchanged, depending — that we could cleverly view "unchanged" as "add 0", and then once we had "add-1-or-0, depending" we could refactor. However, cons is not quite like that: there is no way to call cons without adding something onto another list. So we can't use that same trick3.
  3. (5pts) Write aliens-remaining*, which is similar to aliens-remaining except that is takes in a list of missiles and returns the all the aliens that are not hit by any of them. It should, of course, call aliens-remaining as a helper.
    Note: This function is kinda a “nested loop”, but we avoid that by processing a single-list, and for each element calling a helper function that acts as an “inner-loop”.
  4. (5pts) Write missiles-remaining and missiles-remaining*, which account for what bullets are left after a collision.
    Note: If you leave this 'til last, it’s okay; if your overall update-world has missiles continue after removing an alien, the game is still playable.
  5. (5pts) Write a function so that you can tell if the game is over (that is, if the ship is hit by a missile). Use helper functions as appropriate.
  6. (5pts) Modify your update-world so that its the aliens and missiles in the updated version account for collisions. (No further test cases required, beyond what you had for those functions, though myself, I chose to include one more test case for each of these functions.)
  7. (10pts) Modify your update-world so that the alien fleet changes whenever the rightmost- or leftmost-alien doesn't overlap with the screen. Use helper functions appropriately.
    Alternately (for just a couple points, but easier) you can just have the fleet change direction at hard-coded locations.
  8. (0pts / optional) Make the aliens fire missiles, occasionally.

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]
          )
and you can play your game. You might even add a stop-when clause to big-bang (providing a function that takes in a world, and returns a boolean).


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 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.      
3 But with higher-order-functions, you can still do some refactoring: you can say “we always do something with the two parts from the template: we either cons them together, or we return-second-arg-ignoring-first.” It's not a major improvement to the code, but for style-points you can try this; anonymous functions are helpful here.      

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.