Computer Science 60
Principles of Computer Science
Fall 2006

Assignment 5: Spampede and Fun with Rex
Part 1 Due Wednesday, Oct 4, 5pm
Part 2 Due Sunday, Oct 8, 11:59pm

Suggested Reading for this week: Keller Chapters 2 and 3. You may wish to read over this material to reinforce your grasp of rex concepts.

Please start this assignment early. It's fun and challenging. There are two parts: Part 1 is rex and some of Spampede and Part 2 is finishing up Spampede.

A reminder also that the first exam will be in class on Thursday, October 5.  The exam will cover material up to, and including, the lecture before the exam. You may bring an 8.5 by 11 sheet of paper with writing on both sides (your own writing please). Write down anything on that sheet that you like. The purpose of this sheet is to minimize memorization so that you can concentrate on concepts instead. You will submit the sheet with your exam but will get it back.

To help you have time to study for the exam, we have split this assignment into two parts with two different due dates.  Please note the earlier due date for part 1!

Summary of What's Due When

The explanation below is long and somewhat involved.  To be absolutely certain you know what's due when, here's a summary:

Part 1, Due Wednesday Oct 4, 5pm:

Part 2, Due Sunday, Oct 8, 11:59pm

A.    Playing with Rex! [35 points] (All due with Part 1)

In this part of the assignment, you will have a chance to write some fun rex functions.

Type rex at the prompt to enter the rex interpreter. You can exit rex at any time by pressing CTRL-D (control key and D). (By doing this, you will lose all of the functions that you defined while you were in the interpreter.) For more documentation, see the rex reference guides available from the "Reference Guides" link on the course homepage.

Use your favorite editor (emacs, vim, etc.) to create a file called hw5.rex. You'll write your functions for this assignment in this file. After you write each function, we recommend that you save and close the file. Then, test those functions in rex. Remember, you can start rex with a file by typing rex hw5.rex or you can just type rex and once you are there you can include a file by typing *i hw5.rex at the rex prompt.

Important information on testing: For this part of the assignment, your grade will be based both on the correctness of your functions and completeness of your testing.  You should test each function on several inputs, paying special attention to "hard" or "boundary" cases.   It is the diversity of the tests that matters, not the absolute number, so you don't need to go overboard with the number of tests you choose to run for each function.  You should create a text file called hw5tests.txt that shows the results of running your tests in the rex interpreter.  (You can copy from rex and paste into your favorite text editor--let us know if you have problems with this).  Submit both your rex functions (hw5.rex) and your tests (hw5tests.txt) when you submit this assignment.    

In this part of the assignment, you may use any built-in functions which we have seen in class. You may also define your own additional helper functions if you wish. For full credit, try to keep your code simple - all of these functions can be implemented very succinctly.

Your hw5.rex file should contain programs ("functions") for the following:

  1. [3 Points] A function called find_index(X, L) which returns the index of the first occurrence of element X in list L. The first item in the list is assumed to have index 0. If X is not an element of L then this function should return a number larger than the index of any element in the list. For example here is some sample input and output:
     rex > find_index(1, [1, 2, 3]); 
    0

    rex > find_index(3, [1, 2, 3]);
    2

    rex > find_index(42, [1, 2, 3]);
    4
    Note that since 4 is not in the list [1, 2, 3], the function returned a number larger than the length of the list, which is 3. My solution printed 4, but any number larger than 3 would be OK in this case.

  2. [3 Points] A function remove(X, L) which constructs a list identical to L except that every occurrence of X in L has been removed. The order of the unremoved elements should not be changed. If X does not occur in L then, naturally, this function simply constructs a list identical to L. For example here is some sample input and output:
     rex > remove(3, [5, 4, 3, 2, 3, 1, 2]);
    [5, 4, 2, 1, 2]
  3. [2 Points] pair(X, L) returns a list of all pairs (a pair is a list with exactly two elements) in which the first element is X and the second element is taken from L. For example here is some sample input and output:
     rex > pair(1, [2, 3, 4]);
    [[1, 2], [1, 3], [1, 4]]
  4. [3 Points] all_pairs(L1, L2) takes two lists as arguments and returns a list whose elements are all the pairs with the first element from L1 and the second element from L2. For example here is some sample input and output:
     rex > all_pairs([1, 2, 3], [4, 5]);
    [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
  5. [5 Points] dupereverse(L) takes a list L whose elements could be numbers or lists (the elements of those lists could be numbers and/or lists). This function returns a list which is the reversal of L. If L contains a list, then that list gets recursively reversed. For example here is some sample input and output.
     rex > dupereverse([1, [2, 3], [4, [5, 6, [7, 8], 9] ] ]);
    [[[9, [8, 7], 6, 5], 4], [3, 2], 1]
    You may use any built-in rex functions. In particular, the atomic predicate (take a look at how we implemented flatten) will be especially useful here, and you may (or may not) choose to use reverse in your solution.

  6. [3 Points] uniquify(L) returns a list identical to L except that only the first occurence of each item of the list is saved. That is, all duplicates of an item are removed except for the first occurence. For example here is some sample input and output:
     rex > uniquify([1, 2, 1, 3, 2, 4, 2]);
    [1, 2, 3, 4]
  7. [3 Points] height(T) takes a list representing a tree as input (remember from lecture that a tree is just cleverly represented as a list!) and returns the height of the tree. The height of the empty tree is defined to be 0. The height of a tree with just one node is 1. The height of a tree, in general, is the maximum number of nodes among all paths from the root of the tree to a leaf of the tree. For example here is some sample input and output:
     rex > mytree = [5, [3, [], []], []];
    1

    rex > height(mytree);
    2
  8. [3 Points] Create a function called minimum(T) which takes a list representing a binary search tree as input and returns the smallest element in that tree. For example, here is some sample input and output:
     rex > mytree = [10, [3, [], []], [42, [20, [], []], [60, [], []] ]];
    1

    rex> minimum(mytree);
    3
  9. [10 Points] Write a function delete(X, T) which takes a value X and a list T representing a binary search tree and returns a binary search tree with all of the elements of T except with X removed. You can assume that X is definitely in the tree T. You should use the algorithm described in class for removing an item from a binary search tree. You'll need to use the minimum function that you wrote in the previous problem to do this. Remember that to delete an element from a binary tree is not difficult if the element has 0 or 1 children. If the element (call it X) to be deleted has 2 children, we find the next larger element in the tree (call it Y) (the minimum element in the right subtree), remove Y, and place Y where X used to be. Now, we must do this using recursion! (Take a look at the insert function that we wrote in class. The recursion in delete will use similar ideas!) For example here is some input and output:
     rex > mytree = [10, [3, [], []], [42, [20, [], []], [60, [], []] ] ];
    1

    rex > delete(10, mytree);
    [20, [3, [], []], [42, [], [60, [], []]]


B. Spampede! [65 points total: 20 in part 1, 45 in part 2]

The Spampede game takes advantage of the double-ended Queue (Deque) class you wrote in Assignment 4 in order to implement a centipede in search of spam within a simple Maze-like world.

Example Applet

You can run an example Spampede applet at www.cs.hmc.edu/~alvarado/applets/Spampede.html.

You can also run the "starter" Spampede applet which we saw in class by clicking here. We have provided the code for this starter applet and you will be modifying it until you have the working game!

Files and Classes

You will need to write the Spampede.java file that contains your Spampede class extending Applet. The "starter" applet Spampede.java and its html file Spampede.html are provided for you in /cs/cs60/assignments/assignment5/Spampede/.

In addition, you will need to use the following classes. These files are also provided:

Finally, we have also provided the following files which you may wish to use (totally optional):


You should copy all of these files to your cs60 directory from /cs/cs60/assignments/assignment5/Spampede.

Getting the applet running

Make sure that you can run the provided "starter" applet from an Applet Launcher or from your webpage. If you're using your webpage, here are things to remember:

  1. Make sure you have the Java Console open for your browser for debugging.
  2. Compile everything with javac *.java .
  3. Copy everything to your web directory with ./copyFiles. (If you are copying the files manually, please make sure not to copy the .java files.)
  4. Now your Spampede applet (in it's current state) should appear from any web browser at the address
     http://www.cs.hmc.edu/~<your turing login name>/Spampede.html

Writing the applet

Once the above steps work for you, you're ready to write Spampede by the modifying Spampede.java file so that you

As you write your code, please compile and rerun the applet often to make sure you're on the right path. Use the Java Console (or Applet Launcher) to help with debugging and error-detection. Basically, this means many iterations of the compilation, copying, and testing steps above.

What does the code have to do?

The Spampede applet gives a user control over a spam-seeking centipede. Key presses from the keyboard change the direction of the centipede's movement in order to intersect snacks (spam) that appear at random places on the screen. For each snack consumed, the centipede grows by one segment (a segment is simply one Boardcell). Variations are welcome, but as a default you should implement the following.

Part 1 requirements:

Part 2 requirements:

I want more!

If you haven't had enough of the Spampede.java file at the end of this assignment, there are a couple of specific items and an open-ended invitation to improve on the applet for optional bonus credit. (Up to 3 points for each additional feature for up to 9 bonus points in total.) However, please do the rex part of this assignment first. (The rex part is important and will help you prepare for the exam.)

If you add optional features, please document them in ALL UPPERCASE in a comment at the top of your Spampede.java file so that the grutors will see this.

Submission and Testing

There are a lot of files that make up this assignment, so the easiest thing to do is to run


> cs60submitall
which will submit most of them. If you have images or sound files, they will not be submitted. However, you should just make a note of this at the top of your Spampede.java file and copy those images and sound files (but not source code!) to your ~/public_html directory. The graders will be able to grab them from there.

Please submit all of your Part 1 code as problem 1, and all of your Part 2 code (including resubmitting ALL code needed to run Spampede) as problem 2.