CSCI 151 - Prelab 3 - Fall 2016 Simply a-maze-ing!!

Due at the start of class on Monday February 20

In this prelab, you will familiarize yourself with some of the design and implementation issues in the upcoming lab 3. Please write or type up your solutions, and hand in a paper copy at the start of class on Monday.

Overview

In this lab you will be writing a program that will read in a maze and then find possible paths from the start to the exit using different techniques.

Part 1 - Representing the Maze

First let's talk about your basic maze. It has walls and pathways, and it has one (or more) starting point(s) and one (or more) exit point(s). (To keep things simple, let's just assume it has no more than one of each.) Furthermore, one wall is just like another, and any open space (not including start and finish) is also identical. So, we can think of a maze as being made up of individual squares, each square either empty, a wall, the start, or the exit.

Below is a graphical representation of a maze. The green box represents the start, the red box the exit, and the black squares the walls.


We can represent 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

The Square Class

    Suppose you want to print out a representation of a Square class using the following substitutions:

     

    Input Output Meaning
    0 _ empty space
    1 # wall
    2 S Start
    3 E Exit

    Question 1: Write a toString method that returns the appropriate character (in this case, write actual code rather than pseudocode). Assume that the input is stored in a field called type. This is a perfect time to use a switch() statement [Weiss 1.5.8], although nested if-then-elses would also work.

The Maze Class

Once we have Squares, we should be able to set up the maze itself. Assume that the Squares are stored in a 2-dimensional array called maze similar to the following

Square[][]  maze = new Square[numRows][numCols];

    Question 2: Write a toString() method that returns the maze in textual format. To make this easier to read, call your loop variables something like row and col.

    For example, the maze above would be returned by toString as follows:

        _ _ _ _ _ _ # _ _ _ _ _ _ 
        # # _ # # # # # # # _ # _ 
        _ # _ _ _ _ _ _ _ _ _ # _ 
        _ # _ # # _ _ # # # _ # _ 
        _ _ _ # _ _ _ _ _ # _ # _ 
        _ # # # # # _ # _ # _ # _ 
        _ _ _ _ S _ _ # _ _ # E _ 
    

    Note that this is just one long string with embedded '\n' characters to terminate lines.


Part 2 - Stacks and Queues

In this section of the lab you will implement your own stack and queue. For now, we'll just get some practice with them.

Question 3: Draw the contents of stack and queue data structures for each step in the following sequence: add(1), add(2), remove, add(3), add(4), remove, remove, add(5). Assume both structures are initially empty.

     Queue  add(1)  
     add(2)  
     remove  
     add(3)  
     add(4)  
     remove  
     remove  
     add(5)  

     Stack
    add(1) add(2) remove add(3) add(4) remove remove add(5)
     






     







Part 3 - Solving the Maze

Now that you have a maze, and you have stacks and queues, we can get down to business! The application portion of this lab will be to write a MazeSolver class (and associated classes), which will bundle up the functionality of determining whether a maze has a solution---that is, whether you can get from the start to the finish (without jumping over any walls). The algorithm one usually follows goes something like this: start at the start location and trace along all possible paths to (eventually) all reachable open squares. If at some point you run across the finish, it was reachable. If not, it wasn't.

Boiling this down into pseudocode, we have the following:

At the start

Each step thereafter