// Author: David Riley
// Date: July, 2002

/*  invariant:	this is a rectangular grid of 20 pixel by 20 pixel square cells that 
                    	displays upon a background canvas.
            		and forAll (c : a cell of this   |   c.isEmptyCell() implies
									c displays as a white square with a black border
 					and forAll (c : a cell of this   |   not c.isEmptyCell()) ==
									c displays as a non-white square 
									or a numbered square  */
import java.awt.event.*;
public class MazeGrid  extends Grid {
    private boolean pathExists;
    private int endRow, endCol;
    private int rowMax, colMax;
    
    /*	post:	this is a rectangular array of rowNum rows and colNum columns
            	and forAll (c : a cell from this  |  c.isEmptyCell())  */
    public MazeGrid(int rowNum, int colNum)   {
        super(rowNum, colNum, "Run the Maze");
        rowMax = rowNum;
        colMax = colNum;
    }
    
    /*	post:	exists(a path of previously empty squares from (startRow, startCol)
						 thru (endRow,endCol)) implies such a path is numbered sequentially
				and not exists (a path of previously empty squares from 
								     (startRow, startCol) thru (endRow,endCol))
							implies (this == this@pre)   */
    public void findPath(int sr, int sc, int er, int ec)   {
		endRow = er;
		endCol = ec;
		pathExists = false;
		checkAndNumberPath(sr, sc, 0);
    }
    
    /*	pre:	The path from (startRow,startCol) to (r,c) has been numbered 
				through counter.
		post:	exists(a path of previously empty squares from (r, c)
						 thru (endRow,endCol))  if and only if   pathExists
				and pathExists implies an empty path is numbered sequentially 
				and pathExists implies (this == this@pre)  */
    private void checkAndNumberPath(int r, int c, int counter)   {
        if (0<=r && r<=rowMax() && 0<=c && c<=columnMax() && isEmptyCell(r,c)) {
            counter++;
            setCellToNumber(r,c, counter);
            if (r == endRow && c == endCol)   {
                pathExists = true;
            } else {
                checkAndNumberPath(r+1, c, counter);
                if (!pathExists)   {
                    checkAndNumberPath(r, c+1, counter);
                } 
                if (!pathExists)   {
                    checkAndNumberPath(r-1, c, counter);
                } 
                if (!pathExists)   {
                    checkAndNumberPath(r, c-1, counter);
                }
                if (!pathExists)   {
                    setCellToEmpty(r, c);
                }
            } 
        }
    }   
    
    public void actionPerformed(ActionEvent e )   {
        findPath(0, 0, rowMax-1, colMax-1);
    }

}
