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

homelecturesrecipeexamshwsD2Lbreeze (snow day; distance)

hw06
Invaders II: list-processing

Due Nov.02 (Mon.) in class.

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

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 appropriate steps1 of the-design-recipe—the design recipe: final version. In particular, test cases alone might be worth half the credit for a function. Unless otherwise indicated, two test cases will suffice for most problems, if they are testing different situations.

Unless otherwise indicated, all problems are to be written in Racket. As mentioned in class: do not call any of the following functions:

  1. (5pts) Write the function count-bigs : number, list-of-number → 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.
      (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)
      
  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 (or, my-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 hw05 racket file to one that we'll use for hw06. 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 hw05 solution or in the posted hw05 solution2. Any changes you make (e.g. updating the world examples to have a list-of-aliens) will be moved below the dividing line. You do not need to include part A (problems 1,2) in your part B hardcopy.

Right now, you can go ahead and move all the world definitions, examples, and functions below the dividing-line, since we'll be updating world to include a list-of-aliens. 3

  1. (5pts) List-of-aliens:
    1. Give the data-definition for list-of-alien.
    2. Give at least 4 example values of this type. Your last example should contain at least six aliens (not all in the same row, nor all in the same column); you may use this as the aliens in your game's initial world.
    3. Write the template for any alien-processing function.
  2. (5pts) Write draw-aliens : list-of-alien, image → image, similar to the draw-* functions from hw05—Invaders I; grammars. (One test case will suffice; write it before you write the code, to make your life easier.)
    hint: When creating the expected-output for you test case, feel free to call draw-alien. This will help remind you how we drew multiple items onto a single image, back in hw05 #4c and #4e.
  3. (5pts) Modify your world struct so that it includes two more fields: a list of aliens, rather than just a single alien; and: is the alien fleet currently marching to the left, or to the right? (A boolean could capture this, but I recommend using a number — perhaps +1 or -1. This way, it can immediately generalize to be the fleet's x-velocity.)

    You'll need to make updates to your examples of world-structs, along with draw-world, world-handle-key, and update-world. (For now, update-world need only move all the aliens in the fleet's direction; below we'll overhaul it further to handle the fleet reaching the edge of the screen.) Verify that all updated test cases still pass, of course.

  4. (5pts) Write alien-collide-bullet?, which determines whether a alien overlaps with a bullet. It's okay to approximate overlap by only looking at the bullet's “bounding box”, and calling overlap?. Have two test cases (this is reasonable, given that you already have overlap? fully tested).
  5. (5pts) Write aliens-remaining : list-of-alien, bullet → list-of-alien which returns all aliens in the given list which are not colliding with the given bullet.
    restriction: Do not use the built-in function remove; the goal of this assignment is to be able to process the list yourself.
    hint: We previously saw that when an if expression was either adding 1 or not, to some value, we could reduce it to add-1-or-0, and then factor out the “some value” from the if. However, cons doesn't have the equivalent to zero that + has: there is no way to say “cons nothingness onto a list, returning the same list”. So we can't use that same trick4.
  6. Add the player firing: If the player presses the "fire" button, the world's bullet is replaced with a new one just above the cannon.

    Design discussion: When playing the game, after a bullet hits an alien, there is no bullet left in the world. But our world structure always has a bullet field! How to fix this?

    Similarly, if the bullet hits an alien, it should disappear. (This isn't part of handling a keypress. Which function should check for this?) This may involve a helper function, or you can look up ormap and use a lambda-expression.

  7. Write leftmost : list-of-alien → real which returns the leftmost coordinate of any alien in the list. If the list is empty, you can return any real. Similarly, write rightmost and bottommost.
    challenge: Instead of the above three functions, write a single one which will handle all cases. For example, you might have most : list-of-alien, (alien→real), (real,real→real) → real. (The third input will either be max or min; it's up to you to figure out what you might use as the second input.) Alternately, you can use calls to map and sort.
  8. Now, upgrade your update-world so that it moves the alien fleet down and reverses direction, when the left- or right-most alien is near/at/beyond the edge of the screen. Use map, and a function like (λ (a) (move-alien a +1 0)).

    language-level: In order to pass a function to map, you'll need change: Language » Choose Language… » Intermediate Student.
    remember:Feel free to use let*, if you like.

  9. Extra credit: Add alien-bullets to the world. I'll leave it to you do decide how to best do this. Helper functions might include bullet-overlaps-aliens? and bullets-remaining. Alternately, using filter and higher-order functions (and, andmap/ormap) can significantly simplify this. But if you have any problems, I recommend making the functions and their test-cases, so you can quickly find where the error is.

All the above should have their tests, as well as signatures and (brief) purpose statements. Only after all tests pass, you can check that the following works:

(require 2htdp/universe)

(big-bang some-initial-world
          [on-key  world-handle-key]
          [on-tick update-world]
          [stop-when (λ (w)  (bottommost ) )]
          [to-draw draw-world])


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 hw06 may use any/all of the hw05-soln.rkt; of course, cite any code you use like this (including a URL), just as would do for any purpose, hw or not.      

3 Alternately, you can leave world untouched, but make a new structure named “world2”. Presumably you'd copy and slightly-modify the world examples and functions.      

4 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 or we “return-second-arg-ignoring-first”.” It's not a major improvement to the code, but you're welcome to try it out as an experiment. Anonymous functions are helpful here.      

homelecturesrecipeexamshwsD2Lbreeze (snow day; distance)


©2015, Ian Barland, Radford University
Last modified 2015.Oct.30 (Fri)
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Rendered by Racket.