CMPSCI 187: Programming With Data Structures

David Mix Barrington

Fall, 2011

Programming Project #2: Finding Paths in a Maze

Corrections and additions in green posted 19 September.

Correction in brown made 19 September.

Originally posted 19 September 2011, due at 11:59 p.m. EDT on Wednesday 28 September 2011, by placing .java files in your cs187 directory on your edlab account. Please place files for this assignment in a subdirectory of cs187 called "project2".

As we get questions on this assignment we will put answers on the Q&A page.

Note that you may make use of the posted solution to Project #1, with attribution.

Goals of this project:

  1. Write a program using inheritance.
  2. Write a program using a stack object from a predefined generic class.
  3. Use the depth-first (or backtrack) search method.

In Project #1 we created a Maze class, containing a two-dimensional array of Cells that could be open or closed. Our task here is to determine whether a path exists from one cell in a Maze to another, and return an example of such a path if it does. Here a path is a sequence of open cells, the first being the source and the last the destination, where each two consecutive cells are neighbors, the first being one cell directly up, down, right, or left of the other.

Note that if the source and destination are the same node, then there is a valid path with one cell in it, the source/destination.

As explained in lecture, we will need to mark cells as "seen" during our search, which will require us to modify the Cell class so that each cell has an additional boolean field. We will create a new class SCell that extends Cell. However, we cannot easily have our new Maze class extend the old one, for various reasons. So we will rewrite Maze, including the moves method, to contain SCell objects instead of Cells. This should involve just replacing "Cell" with "SCell" wherever it occurs in the code for Maze.

We then just have to add two new methods to Maze:

Here source and dest must be two cells in the calling Maze object, specified by their X and Y coordinates in the Maze. If there is any path from source to dest, then the path method must return some such path (any such path will do) and the isPath method must return true. If there is no such path, then the path method must return an array of length 0, and the isPath method must return false.

It will be easiest to write path first, and have isPath call path.

As discussed in lecture, the way to implement path is to create a Stack<SCell> object, which will contain a trial path starting from source. We mark cells as "seen" if they are in the trial path or have already been completely processed. Completely processing a node means checking all of its open neighbors given by the moves method. To check a neighbor, we push it onto the stack and begin processing it. When we finish with a node, we pop it off the stack and go on to the next unseen open neighbor, if any, of the node now on the top of the stack. If we complete the search without seeing dest, then no path exists.

We don't want our methods to have side effects, so make sure that path sets every cell in the maze to "unseen" when it is done.

Note that L&C carry out a similar project, with different data types, in Section 4.5. -- you may borrow from their code with attribution.

Last modified 19 September 2011