home—lectures—recipe—exams—hws—D2L—zoom (snow day)
list processing
Galaga II
Due
part (a) Feb.26 (Fri) 23:59;
part (b) Mar.02 (Tue) by start of class.
For this homework:
- You may not call place-images (plural), though you may(should) call place-image.
- You may not call append.
- You may not call list, except perhaps to make test-case inputs/results.
(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:
- list (except when making test-cases)
- append (unless you write it yourself)
- remove/remove* (unless you write it yourself)
- place-images (plural) (unless you write it yourself); calling place-image (singular) is fine/intended.
- any functions with a “!”, such as set! and set-rest!.
Your name and the assignment-number
must be in a comment at the start of the file
All functions/data must include the appropriate steps 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
- 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!
- 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.
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.
- For List-of-aliens,
- Give the datatype-definition for list-of-alien
but no define-structs are necessary, since using the built-in cons suffices.
- Give at least 4 example values of this type.
Your last example should contain at least four aliens; you may use this as the aliens
in your game's initial world.
- Write the template for a list-of-alien processing function.
- Make some examples of List-of-missiles.
(You don't need to give a datatype-def'n or template (since they are
so similar to those for List-of-aliens), though.)
- Moving lists-of-objects.
- Write
move-aliens : list-of-alien → list-of-alien
or, if using my posted solution,
list-of-alien, real, real → list-of-alien,
which returns a list where each alien has moved.
Note: Your test cases can call our already-tested move-alien,
which in turn suggests your code canshould! 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.
- Write move-missiles, similarly.
part b
In the original Galaga, the ship can die either
by being hit by a missile, or by being hit by a diving alien.
For this homework you only need to implement one of these two.
Feel free to gnore any of the instructions below involving the feature you aren't implementing.
You are of course welcome to implement both,
but at the very least complete just one of these two features
before starting much work on the other.
- To determine collisions, we will be happy with the hack of using
bounding boxes
:
We'll say that an oval and a triangle collide if the imaginary rectangles containing each of them overlap.
That's expedient, because it's easy to
tell if two rectangles overlap?.
-
Write alien-collide-missile?,
which determines whether a single alien overlaps with
a single missile.
Then use this as a helper to write
alien-collide-missiles?,
which determines whether a single alien overlaps with
any missile in a list-of-missile.
Depending on your datatype-definition for alien,
these functions might also need to be additionally provided the fleet's position.
- Now, write
aliens-remaining : List-of-alien, List-of-missile → List-of-alien
or, if using my posted solution, perhaps
list-of-alien, List-of-missile, real, real → list-of-alien
which returns all aliens after accounting for any missile-collisions.
- Write either
ship-collide-alien?
and
ship-collide-aliens?,
or
ship-collide-missile?
and
ship-collide-missiles?.
- Write
missiles-remaining, which takes in a list of missiles,
and returns a list of those missiles that
survive
(are still on-screen).
hint: An easy way to check if on-screen: does their bounding-box
overlap?
the screen?
If you want, you may also remove missiles that have just collided with an alien,
but this is not required,
just to save you from writing missile-collide-aliens.
For each of the functions, have (of course) 2-3 test cases, incl. one with an empty-list.
Two tests suffice for individual-collisions, since an already-tested
helper overlap? is provided.
For lists, three tests should suffice: lists of length zero, one, and “many”.
And the tests for list-of-length-0 is trivial, and the test for list-of-length-1 is similar to your earlier tests.
- Drawing functions:
- Write function
draw-aliens,
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-alien (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.
- Write draw-missiles similarly.
- Alien actions:
We will need (in the next step)
to be able to get aliens to
(either) fire missiles,
or to start diving To assist with that, write (at least) one of:
- missile-from : alien -> missile
Depending on your datatype-definition for alien,
these functions might also need to be additionally provided the fleet's position.
- tell-to-dive : alien, List-of-alien -> List-of-alien,
which takes returns a list just like its input, except that
the alien that is equal? to the one passed in has started diving.
(You'll call the first and last on an alien randomly chosen from the list of all current aliens.)
- Worlds:
Define a world
structure which contains
one ship, a list of missiles,
and a list of aliens,
as well as
a “fleet direction” (whether the aliens are currently marching to the right, or to the left).
My own solution also needed a fleet-x, since that info wasn't stored inside each alien.
As usual for our data-definitions,
make examples of the data (at least two).
- Give a template for world-processing functions.
- 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 ship-handle-key,
and your test cases will largely crib from that.
However, this function will also handle firing, which adds a new missile to the world.)
- As your implementation needs it:
write a function
to determine what direction the
fleet
should move next
(which occasionally changes from left to right and back).
I wrote two helper functions rightmost : list-of-alien -> alien
and leftmost.
- Help integrate (at least) one of the alien actions above
(initiating diving and firing)
by a having function that choose an alien from a list, to start that action.
You'll call this function from the next step;
it probably won't be called every tick, though.
hint: The expression
(list-ref [list] (modulo (* 12343 [number]) (length [list])))
can be used to select a seemingly random element from a list.
If, for the [number] you use something like
the fleet's x-position, then you can write unit-tests with
a predictable result,
even if the behavior appears random to users.
- 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.
- Write the function game-over? : world → boolean.
- 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.
home—lectures—recipe—exams—hws—D2L—zoom (snow day)
 This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarland radford.edu |
 |