This is due at 6PM on Tuesday, March 22
In this lab you will implement an algorithm for finding your way through a maze. The algorithm needs a structure for temporary storage and you will implement it twice -- once with stacks and once with queues. For even more variety you will use ArrayLists to implement stacks and a dynamic node structure to implement queues.
This lab is a little larger than past labs; it has many different pieces that all need to work together. Most pieces are small, but it may take some additional patience on your part.
You may work with a partner on this assignment, and on all subsequent labs, both during and after the lab session.
I have supplied starter code, including a folder of mazes here: Lab3.zip. You should expand this into your CS151 folder. It will create a new, partially implemented Eclipse project named "Lab3". Change the name of the project folder to Lab3<your last name> Inside this folder you should see a folder named "mazes" and a "src" folder that contains a package "lab3" with 10 .java files. There are numerous errors in those files due to unimplemented code, but we will fix those as we go along. Open a new project in Eclipse using this folder as the project folder.
Here are the 10 files you should find in this project:
Your work in this lab will be:
Methods are specified in the interface files supplied in the starting point code. Be sure to throw the correct exceptions. For the linked Queue implementation, you should make a nested class to handle the nodes. You don't need to create a separate file to do this, instead just have the class description in the same file as MyQueue but without the "public" modifier.
Before continuing, you should add JUnit tests for MyStack and MyQueue that performs testing on your data structures.
The Maze implementation is complete but you need to understand it to write the MazeSolver. We represent a maze as a rectangular array of Squares, each Square being empty, a wall, the start, or the exit.
Below is a graphical representation of the maze found in the file maze-2. The green box represents the start, the red box the exit, and the black squares the walls.
We describe such a maze with a text file of the following format. The first line of the file contains two integers. The first indicates the number of rows (R), the second, the number of columns (C).
The rest of the file will be R rows of C integers. The value of the integers will be as follows:
0 - an empty space 1 - a wall 2 - the start 3 - the exit
In terms of coordinates, consider the upper left corner to be position [0,0] and the lower right to be [R-1,C-1].
For example, this is the text version of the maze above (start is at [6,4] and exit at [6,11]).
7 13 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 2 0 0 1 0 0 1 3 0
Make sure you understand how this array of numbers corresponds to the pictured maze.
One of the Lab3 files is class Square, which represents one entry in the maze. A Square has an instance variable that represents its type (space, wall, start, or exit). Class Square defines constants that represent the four types of Squares. You should always refer to them by name (for example, inside the Square class use WALL; outside this class use Square.WALL), rather than specific values (such as 1). A leprechaun should be able to modify all of your constant values (perhaps changing WALL to 101) without affecting your program at all. One of the major goals of this course is learning to make your programs leprechaun-proof.
A Square needs to know where it is on the grid so it can find its neighbors. Each Square has private variables of type int named row and col to represent it's location within the maze.
Class Square also has the following methods:
To save you some time, we have supplied a class Maze to represent the logical layout of a maze. This contains a class variable maze that is a 2D array of Squares. It also has integer variables numRow and numCols that give the size of this array. Initially, this array will be empty and numRows and numCols will be set to 0. We will use a loadMaze() method to populate it.
Class Maze includes the following methods:
loadMaze()
method described next.
Class Maze is complete; you shouldn't need to change this file. Before you continue, you should test that the Maze class integrates correctly with your Square class. You can do this by creating a JUnit test suite. Among other things, this test should load a maze from one of the supplied files, get the neighbours of some specific square (the start square, for example), and assert that (1) there are the correct number of neighbours, and (2) the neighbours are in the correct locations. You probably should do this for the corners and border cases, at least. There should also be tests to print out the maze, and to confirm your getStart() and getFinish() methods return the correct squares. Note that you can refer to the test mazes from inside Eclipe through names such as "mazes/maze-2." There is no ".txt" extension in these file names.
Now that you have a maze and working stack and queue data structures, we can use them to solve mazes. You will next implement the application portion of this lab, writing the MazeSolver, MazeSolverStack, and MazeSolverQueue classes which will find the solution to any maze file. You should pay attention to the structure here. We are producing two programs that solve mazes: one uses stacks and the other uses queues. We will make an abstract class MazeSolver with all of the behavior that is the same for both versions, then concrete subclasses MazeSolverStack and MazeSolverQueue with the parts that are unique to just one of the versions.
Our maze solving algorithm goes like this: begin at the start location, and trace along all possible paths to (eventually) visit every reachable square. If at some point you visit the finish Square, it was reachable. If you run out of squares to check, it isn't reachable.
Boiling this down into pseudocode, we have the following:
At the start
Each step thereafter
Note that this pseudocode is entirely agnostic as to what kind of worklist you use (namely, a stack or a queue). You'll need to pick one when you create the worklist, but subsequently everything should work abstractly in terms of the worklist operations.
Create an abstract class MazeSolver that will implement the above algorithm, with a general worklist. Its abstract methods will be implemented differently depending on whether the worklist is a stack or a queue. The MazeSolver class should have a non-public class member of type Maze, and should have the following methods:
ArrayList<Square>path = new ArrayList<Square>( ); while (!stack.isEmpty()) { Square t = stack.pop(); path.add(t); } return path;
Now we just need to create the two implementations of the MazeSolver class. MazeSolverStack is complete. Observe the way it creates a MyStack object and uses it to implement the abstract worklist methods from the MazeSolver class. You need to do something similar for MazeSolverQueue.
You should now be able to run the MazeApp application and watch your algorithms solve mazes.
You should hand in a zipped copy of the project folder for this lab. That should contain all of the files needed to allow us to run MazeSolverStack and MazeSolverQueue. Remember that the name of everyone who worked on the program should be in a comment on every code file. If you adhered to the honor code in this assignment, add a README text file to your project folder with the text
I have adhered to the Honor Code in this assignment.
You want to keep the graders happy. If there are portions of these programs that you know are not working correctly, it would be helful if you included information about what does and what doesn't work in your README file.
Go to your csci151 folder and make a compressed version of your project folder. On a Mac select this folder and select Compress from the File menu. On Windows right-click on the project folder and select Send to -> Compressed (zipped) folder. In either case you should get a zip file. Open the Blackboard course site.. Click onthe Course Material link, then on the Lab 3 link. In the Assignment Submission section click on the Browse My Computer button. this will bring up the usual navigation controls that should allow you to select your zipped project file for this assignment. If you worked with a partner only one of you should hand in your work.