Computer Science 42
Principles of Computer Science
Fall 2010

Assignment 9: Spampede!
Due Monday, November 8 by 11:59 PM

Please read the following carefully. There is a lot here!  


  1. All parts of the assignment are individual or pair.  If you work with a partner, you must work with the same partner on all three parts.
  2. You will be submitting several files for this assignment. Please submit every file that you used for your assignment. We will look for SpamMaze.py (Parts 1 and 2), and Spampede.py (Part 3). If you define any other files as part of your project, please submit those too as support files.

  3. This week, we ask that you also submit a file that is typically submitted in any large software project: A text file called README. We have provided a basic README file below on this page. You should edit this file and submit it. The README file constitutes part of your score on this assignment.

This assignment has three parts, which ultimately build to the Spampede game! In Part 1, you will extend the capabilities of your maze solver from HW8 (though you may use our solution code for that assignment if you prefer). In Part 2, you will use the results of Part 1 to build some of the primary functionality of the Spampede game. In Part 3, you will use Part 2 in a graphical application that you (and your friends) can play!


What is the final product?

Provided Files and Setup

Because we are using graphics this week, things are a little complicated, depending on what platform you are running on.  Please download these files, and try out the starter files following the instructions in this section.  Let us know right away if you experience any trouble.

The starter files include the folllowing:

Notes about Spampede.py

Spampede.py uses the tkinter graphics package.   Unfortunately, IDLE also uses the tkinter graphics package!  So these two applications do not really "get along", so to speak.

We recommend this week you DO NOT use IDLE for running Spampede.py.  You can still use it for editing, and if you must use it for running, you'll have to launch IDLE using the -n flag, as described here:
https://www.cs.hmc.edu/twiki/bin/view/CS5/PrettyPicturesGold
(Ignore the stuff about Turtle).

What we recommend is that you instead run Spampede.py from the command line.  Do do this, you simply open up a terminal (command prompt), navigate to the directory where you've got your files, and type (in the labs):

% python -i Spampede.py

This command will only work if you have set your path correctly.  If you have not set your path to point to python, you will need to invoke Python using its full path, e.g.:

% C:\Python27\python.exe -i Spampede.py

This will automatically launch the Spampede application.   Note that when the application quits (you close the window) you will be back int he Python interpreter.  To exit the interpreter press Ctrl-Z, Enter.

If you have any trouble with this setup, come see Prof. Alvarado or one of the grutors right away!

Now, on to the assignment...

Overview

This project introduces and practices a number of different techniques that are common to software engineering, that is the design and implementation of large software projects. Certainly this assignment can only provide a hint at a very rich -- and important -- field.

The Spampede application is clearly a bigger and more complex beast than any you have had to deal with in the past.  Before you begin, we provide you with an overview of the software design behind the game you will create.  Normally, it would be up to you, the developer, to do this design, but because this is your first large-scale project, we have done the class design for you.  

The functionality of the application is broken down into three classes:
The first two of these classes live in a file named SpamMaze.py, while the thrid lives in the Spampede.py file.  Both of these starter files are available for download above.

Part 1:     Improving Maze [20 points], submit in a file named SpamMaze.py (with Part 2)

The first part of this assignment is to improve the Maze class in which you wrote breadth-first search for assignment 8. In particular, you may start with either your own Maze.py file from last week or you may use our solution to that problem provided with the starter files. 

The first thing to do is modify the constructor so that it optionally takes 0 arguments.  This is already in the solution file, or you can copy it from here:

def __init__(self, filename=None):
''' Initialize a new Maze from a File or from the string above '''
if filename is None:
self.rows = len(mazeStrings)
self.columns = len(mazeStrings[0])
self.maze = []
for r in range(self.rows):
self.maze.append([])
for c in range(self.columns):
self.maze[r].append(MazeCell(r,c,mazeStrings[r][c]))
else:
self.maze = None
self.rows = 0
self.columns = 0
self.loadMazeFromFile(filename)
This constructor optionally loads a maze in from the static data member named mazeStrings, which is simply an array of strings contained in Maze file. The nice thing about this is that you can edit your Maze directly in the file!  However, if you like you can still load your mazes from files too.

A more flexible breadth-first-search

The final method to write in the Maze class is

multiBFS(start, destination)
which will implement breadth-first search from start to ANY cell containing the character destination, which will typically be a 'D', representing spam. This method takes a MazeCell start and a char destination as input and it returns a MazeCell object.  The MazeCell it returns is the next MazeCell on the path from start to the nearest can of Spam.  (See below for more details).  This method will be critical in implementing the autonomous spam-seeking behavior of the pede.  Because it is breadth-first search, the method should find the closest destination to the start MazeCell. Note that this is slightly different from the BFS that you wrote on hw8, but you can feel free to modify your BFS or ours to make it suit your multiBFS needs.  Now, you will need to make sure to stop the BFS process when it first reaches a destination of the type that you are looking for!

What should multiBFS do?

This method should have the following behavior:

Testing your code

Be sure to test your code thoroughly before heading to part 2 of this assignment... there is a test in main for this purpose, and you should try editing the mazeStrings in order to make sure it works in a variety of conditions!  You do not need to submit any testing this week, though.



Part 2:     Writing SpamMaze [40 points].  Submit in the same SpamMaze.py file as Part 1

The overview

In this part of the assignment you will create a derived class named SpamMaze that handles the model for the game, which is part 3. A derived class is simply an extension of the data and capabilities (methods) available in the base class. Thus, by starting the code as in the provided SpamMaze file:


class SpamMaze(Maze)
''' The SpamMaze class that you will write '''

you should keep in mind that any object of type SpamMaze IS also an object of type Maze. In other words, a SpamMaze can do everything a Maze can do, and more!  This is identical to the relationship of every object with Java's Object type. Object is the base class of all Java classes.  

The data

Because a SpamMaze object represents the model for the Spampede applet, it needs to keep track of (1) the maze, (2), the centipede, and (3) the spam in the environment. Remember that (1) is already taken care of because your SpamMaze is a derived class of Maze. To keep track of (2) and (3), you should use deques of MazeCells. In particular, you will use two data members:

  # The data members representing the spam and the centipede
self.spamCells = collections.deque()
self.pedeCells = collections.deque()
Recall from HW8 that a deque is Python's built-in  double-ended queue implementation. You can, of course, find all of the methods for a deque using the dir command, as usual.  

The methods

You should, in essence, implement all of the functionality, but not the graphics front end, for the Spampede game inside SpamMaze. At a minimum, you should implement the following methods. You may choose to add more methods - either private helper methods (to help these public methods) - or other public methods for your game to use.

Testing!!

As with Maze, be sure to test your SpamMaze thoroughly in main before worrying about the graphical front-end of the applet in part 3. Below is a main method, which you should feel free to adapt to your implementation and add to the main function provided. Remember that you do not need to write __repr__ -- the version that's already in Maze will work perfectly well!  Again, you do not need to submit this testing this week.


  def main(args=None):
SM = None
if args is None or len(args) != 2:
SM = SpamMaze()
else:
#The filename comes from the command line
filename = args[1]
SM = SpamMaze(filename) # this creates the maze

start = SM.findMazeCell('S') # get the Source
print "Start at", start
# Test multiBFS
print SM.multiBFS(start, 'D')
# Make sure the maze didn't change
print "M is\n" + str(SM)

for i in range(10):
SM.addSpam()
print "M is\n" + str(SM)

for i in range(5):
SM.removeSpam()
print "M is\n" + str(SM)

# Now test the SpamMaze functionality
nextSpot = SM.multiBFS(SM.pedeCells[0], SpamMaze.SPAM)
print "nextSpot is\n", nextSpot
print "SM is\n", SM

SM.advancePede(SpamMaze.EAST)
print "SM is\n", SM
print "pedeCells is ", SM.pedeCells

SM.advancePede(SpamMaze.EAST)
print "SM is\n", SM
print "pedeCells is ", SM.pedeCells

SM.advancePede(SpamMaze.EAST)
print "SM is\n", SM
print "pedeCells is ", SM.pedeCells

SM.advancePede(SpamMaze.SOUTH)
print "SM is\n", SM
print "pedeCells is ", SM.pedeCells

SM.advancePede(SpamMaze.SOUTH)
print "SM is\n", SM
print "pedeCells is ", SM.pedeCells

direction = SM.reversePede()
print "SM is\n", SM
print "direction is", direction

Part 3:     Putting it all together: Spampede.py [40 points].  Submit in a file named Spampede.py

The overview

The Spampede program 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 MazeCell). Variations are welcome (see the extra credit section below)! 

Writing the application

Once the above steps work for you, you're ready to write Spampede by the modifying Spampede.py file with the following things in mind.

As you write your code, please compile and rerun the applet often to make sure you're on the right path. 


A Reminder On What to Submit

Please be sure to submit all of the .py files and any other support files required for all three parts of this assignment. In addition, please submit your README.txt file described at the very top of this web page.

I want more!

If you haven't had enough of the Spampede.py 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 25 points in total.)

If you add optional features, please explain them carefully in the README file.


.