package stack.maze;
/**
* @author Mingkun 2010-4-4
*/
public class MazeCell {
protected static int m = -1;
protected static int n = -1;
private static int[] arr;
private static MazeCell[][] cells; // for instance control
/** next direction: 0-top, 1-left, 2-bottom, 3-right. */
int direction = 3;
/** previous direction (ignore this when getting next direction) */
int preDirection = -1;
final int i;
final int j;
boolean footPrint = false;
protected MazeCell(int i, int j) {
this.i = i;
this.j = j;
}
protected static MazeCell newCell(int i, int j) {
return new MazeCell(i, j);
}
/**
* MUST run this method before using this class!
*
* @param m1 - bottom limit
* @param n1 - right limit
* @param array - arrays to check which cell(s) is accessible.
*/
protected static void initializeForMaze(int m1, int n1, int[] array) {
m = m1;
n = n1;
cells = new MazeCell[m][n];
arr = array;
}
public static MazeCell getMazeCell(int i, int j) {
if (i < 0 || j < 0 || i > m || j > n) {
return null;
}
if (cells[i][j] == null) {
cells[i][j] = newCell(i, j);
}
return cells[i][j];
}
protected boolean isAccessible() {
return arr[i * n + j] == 0;
}
public boolean hasNextCell() {
return direction > -1;
}
public MazeCell getCellInNextDirection() {
if (direction > -1) {
if (direction == preDirection) {
// pop from stack instead of continue in this case.
direction--;
}
if (j == n - 1 && direction == 3) {// lastColumn & require
// Right
direction--;
}
if (i == m - 1 && direction == 2) { // lastRow & require
// Bottom
direction--;
}
if (j == 0 && direction == 1) {// firstColumn & require Left
direction--;
}
if (i == 0 && direction == 0) {// firstRow & require Top
direction--;
}
// return the cell in the nectDirection
if (direction == 3) {
direction--;
return getMazeCell(i, j + 1).setPreDirection(1);
} else if (direction == 2) {
direction--;
return getMazeCell(i + 1, j).setPreDirection(0);
} else if (direction == 1) {
direction--;
return getMazeCell(i, j - 1).setPreDirection(3);
} else if (direction == 0) {
direction--;
return getMazeCell(i - 1, j).setPreDirection(2);
}
}
return null;
}
public boolean isFootPrint() {
return footPrint;
}
public void footPrint() {
footPrint = true;
}
public MazeCell setPreDirection(int preDirection) {
this.preDirection = preDirection;
return this;
}
@Override
public int hashCode() {
return i * n + j;
}
@Override
public boolean equals(Object o) {
if (o instanceof MazeCell) {
MazeCell mazeObj = (MazeCell) o;
return (mazeObj.i == this.i && mazeObj.j == this.j);
}
return false;
}
@Override
public String toString() {
return String.format("[%d,%d]", i, j);
}
}