Difference between revisions of "Recursive Maze Visit"

From dftwiki3
Jump to: navigation, search
Line 3: Line 3:
 
<source lang="java">
 
<source lang="java">
  
public class NQueens {
+
/**
static int[][] board = null;
+
* VisitMaze.java
 +
* @author D. Thiebaut
 +
*/
  
private static void displayBoard( int N ) {
+
 
char escCode = 0x1B;
+
@SuppressWarnings( "all")
 +
public class VisitMaze {
 +
static char maze[][] = null;
 +
static int  dim = 0;
 +
 +
/**
 +
* createRow: takes a string representing a row of the maze
 +
* and breaks it down into an array of chars.
 +
* @param index
 +
* @param s
 +
* @return
 +
*/
 +
private static char[] createRow( String s ) {
 +
char[] temp = new char[s.length()];
 +
 +
for ( int i=0; i<s.length(); i++ )
 +
temp[i] = s.charAt(i);
 +
return temp;
 +
}
 +
 +
/**
 +
* creates a maze by taking strings and breaking them
 +
* down into a 2D array of chars.
 +
*/
 +
private static void createMaze2() {
 +
dim = 10;
 +
maze = new char[dim][];
 +
 +
for ( int i=0; i<dim; i++ )
 +
maze[i] = new char[dim];
 +
 +
maze[0] = createRow(  "###############" );
 +
maze[1] = createRow(  "      #  #  #" );
 +
maze[2] = createRow(  "##### # ### # #" );
 +
maze[3] = createRow(  "#  #  # # # #" );
 +
maze[4] = createRow(  "# # # ### # # #" );
 +
maze[5] = createRow(  "# # # # # # # #" );
 +
maze[6] = createRow(  "#    #  # # E" );
 +
maze[7] = createRow(  "# ##### # # # #" );
 +
maze[8] = createRow(  "#      #  # #" );
 +
maze[9] = createRow(  "###############" );
 +
}
 +
 +
/**
 +
* creates a maze by taking strings and breaking them
 +
* down into a 2D array of chars.
 +
*/
 +
private static void createMaze1() {
 +
dim = 10;
 +
maze = new char[dim][];
 
 
System.out.println(String.format("%c[%d;%df", escCode, 0, 0 ));
+
for ( int i=0; i<dim; i++ )  
 +
maze[i] = new char[dim];
 
 
for ( int c=0; c < N; c++ )
+
maze[0] = createRow(  "###############" );
System.out.print( "--" );
+
maze[1] = createRow(  "              #" );
System.out.println();
+
maze[2] = createRow(  "#            #" );
+
maze[3] = createRow(  "#            #" );
 +
maze[4] = createRow(  "#            #" );
 +
maze[5] = createRow(  "#            #" );
 +
maze[6] = createRow(  "#            #" );
 +
maze[7] = createRow(  "#            #" );
 +
maze[8] = createRow(  "E            #" );
 +
maze[9] = createRow(  "###############" );
 +
}
 +
 
 +
/**
 +
* creates a maze by taking strings and breaking them
 +
* down into a 2D array of chars.
 +
*/
 +
private static void createMaze() {
 +
dim = 10;
 +
maze = new char[dim][];
 +
 +
for ( int i=0; i<dim; i++ )  
 +
maze[i] = new char[dim];
 +
 +
maze[0] = createRow(  "###############" );
 +
maze[1] = createRow(  "      #      #" );
 +
maze[2] = createRow(  "#      #      #" );
 +
maze[3] = createRow(  "E      #      #" );
 +
maze[4] = createRow(  "#            #" );
 +
maze[5] = createRow(  "#            #" );
 +
maze[6] = createRow(  "#            #" );
 +
maze[7] = createRow(  "#            #" );
 +
maze[8] = createRow(  "#            #" );
 +
maze[9] = createRow(  "###############" );
 +
}
 +
 
 +
/**
 +
* clears the screen (works only in Terminal/Console)
 +
*/
 +
private static void clearScreen() {
 +
        System.out.print("\033[2J\033[;H");
 +
    }
 +
 +
/**
 +
* displays the maze, as a 2D array on screen.
 +
*/
 +
private static void displayMaze() {
 +
// bring cursor back to top-left (works only in Terminal/Console)
 +
System.out.println("\033[;H");
 
 
for ( int r=0; r < N; r++ ) {
+
for ( int i=0; i< maze.length; i++ ) {
for ( int c=0; c < N; c++ ) {
+
for ( int j=0; j < maze[i].length; j++ )
if ( board[r][c] == -1 )
+
System.out.print( maze[i][j] );
System.out.print( "Q " );
 
else if ( board[r][c] == 0 )
 
System.out.print( ". " );
 
else
 
System.out.print( "* " );
 
}
 
 
System.out.println();
 
System.out.println();
 
}
 
}
 
 
 
try {
 
try {
Thread.sleep( 2 );//000 );
+
Thread.sleep(100);
 
} catch (InterruptedException e) {
 
} catch (InterruptedException e) {
 
//e.printStackTrace();
 
//e.printStackTrace();
Line 35: Line 125:
 
}
 
}
  
private static boolean recursePlaceQueen( int row, int N ) {
+
for ( int col = 0; col < N; col++ ) {
+
if ( board[row][col] == 0 ) {
+
/**
board[row][col] = -1; // put a queen there
+
* Visit the maze.
displayBoard( N );
+
*/
 +
private static void visitMaze() {
 +
boolean success = recurseVisit( 1, 0 );
 +
if ( success )  
 +
System.out.println( "Success, found a path!");
 +
else
 +
System.out.println( "No path found.");
 +
}
  
//--- if on last row and found an empty spot, we're done! ---
+
/**
if ( row == N-1 )
+
* recurseVisit.  Lands on cell [i,j] of the maze, and
return true;
+
* explore where to go from here, either up, down, right,
 
+
* or left.
updateColumnDown( row, col, N, +1 );
+
* @param i
updateDiagonals( row, col, N, +1 );
+
* @param j
 +
* @return
 +
*/
 +
private static boolean recurseVisit(int i, int j) {
 +
 +
// exit?
 +
if ( maze[i][j] == 'E' )  
 +
return true;
 +
 +
// no, put bread crumb where we landed
 +
maze[i][j] = '.';
 +
 +
// display the maze in current
 +
displayMaze();
 +
 +
// look in all 4 directions around where we are...
 +
int newi =i, newj =j;
 +
for ( int dir = 0; dir < 4; dir++ ) {
 +
switch ( dir ) {
 +
case 0: newi = i-1; newj=j;  break;
 +
case 1: newi = i;  newj=j+1; break;
 +
case 2: newi = i+1; newj=j;  break;
 +
case 3: newi = i;  newj=j-1; break;
 +
}
 +
 +
// we are now looking in a particular direction, 1
 +
// square away, at coordinates (newi, newj) 
 +
 +
// invalid coordinates, outside the maze?
 +
if ( newi<0 || newj<0
 +
|| newj >= maze[0].length
 +
|| newi >= maze.length )
 +
continue;
 +
 +
// the cell at (newi, newj) is empty and hasn't
 +
// been visited yet?
 +
if ( maze[newi][newj] == ' ' || maze[newi][newj] == 'E'  ) {
 
 
boolean success = recursePlaceQueen( row+1, N );
+
// YES!  We can explore going that way!
 +
boolean success = recurseVisit( newi, newj );
 
 
if ( success )  
+
// Did we find the exit going that way?
 +
if ( !success ) {
 +
// Nope... ok, let's backtrack and try another direction
 +
maze[newi][newj] = 'b';
 +
displayMaze();
 +
}
 +
else {
 +
// YEAH!  Found the exit that way... no
 +
// need to explore more... we just return
 +
// Mark where we are as one cell belonging
 +
// to the path to the Exit.
 +
maze[i][j] = '*';
 
return true;
 
return true;
+
}
updateColumnDown( row, col, N, -1 );
 
updateDiagonals( row, col, N, -1 );
 
 
board[row][col] = 0;
 
displayBoard( N );
 
 
}
 
}
 
}
 
}
 +
// if we're here, it's because we've explored all directions
 +
// we could from here, and haven't found a successful path
 +
// to the exit.  So we can't go nowhere interesting from here.
 +
// Return false.
 
return false;
 
return false;
 
}
 
}
  
private static void updateDiagonals(int row, int col, int N, int offset) {
+
/**
int leftC = col-1, rightC = col+1;
+
* main entry point.
for ( int r=row+1; r<N; r++ ) {
+
* @param args
if ( leftC >= 0 ) board[r][leftC]  += offset;
+
*/
leftC--;
 
if ( rightC < N ) board[r][rightC] += offset;
 
rightC++;
 
}
 
}
 
 
 
private static void updateColumnDown(int row, int col, int N, int offset ) {
 
for ( int r = row+1; r < N; r++ )
 
board[ r ][ col ] += offset;
 
}
 
 
 
private static int[][] createBoard(int N ) {
 
board = new int[N][];
 
 
for ( int i=0; i<N; i++ )
 
board[i] = new int[N];
 
 
for ( int i=0; i<N; i++ )
 
for ( int j=0; j<N; j++ )
 
board[i][j] = 0;
 
 
return board;
 
}
 
 
 
 
public static void main(String[] args) {
 
public static void main(String[] args) {
args = new String[] { "8" };
+
// put the maze on the screen.
if ( args.length == 0 ) {
+
clearScreen();
System.out.println( "Syntax: java NQueens N" );
+
createMaze();
System.out.println( "        where N = dimension of board" );
+
displayMaze();
return;
 
}
 
 
 
int N = Integer.parseInt( args[0] );
+
// visit the maze
board = createBoard( N );
+
visitMaze();
 
 
recursePlaceQueen( /* row = */ 0, N );
+
// clean up the maze, remove back=tracks...
displayBoard( N );
+
displayMaze();
 
}
 
}
 
}
 
}
 +
  
 
</source>
 
</source>
 
<br />
 
<br />
 
<br />
 
<br />
 +
<onlydft>
 +
<source lang="java">
 +
/**
 +
* clears the maze of 'b' (back-tracks) or '.'
 +
* and marks the path to the exit with '.'
 +
*/
 +
private static void clearMaze() {
 +
for ( int i=0; i< maze.length; i++ )
 +
for ( int j=0; j < maze[i].length; j++ )
 +
if ( maze[i][j] == '.' || maze[i][j] == 'b' )
 +
maze[i][j] = ' ';
 +
else if ( maze[i][j] == '*' )
 +
maze[i][j] = '.';
 +
}
 +
</source>
 +
</onlydft>
 
<br />
 
<br />
 
<br />
 
<br />

Revision as of 20:17, 22 October 2014

--D. Thiebaut (talk) 20:55, 22 October 2014 (EDT)


/**
 * VisitMaze.java
 * @author D. Thiebaut
 */


@SuppressWarnings( "all")
public class VisitMaze {
	static char maze[][] = null;
	static int  dim = 0;
	
	/**
	 * createRow: takes a string representing a row of the maze
	 * and breaks it down into an array of chars.
	 * @param index
	 * @param s
	 * @return
	 */
	private static char[] createRow( String s ) {
		char[] temp = new char[s.length()];
		
		for ( int i=0; i<s.length(); i++ )
			temp[i] = s.charAt(i);
		return temp;
	}	
	
	/**
	 * creates a maze by taking strings and breaking them
	 * down into a 2D array of chars.
	 */
	private static void createMaze2() {
		dim = 10;
		maze = new char[dim][];
		
		for ( int i=0; i<dim; i++ ) 
			maze[i] = new char[dim];
		
		maze[0] = createRow(  "###############" );
		maze[1] = createRow(  "      #   #   #" );
		maze[2] = createRow(  "##### # ### # #" );
		maze[3] = createRow(  "#   #   # # # #" );
		maze[4] = createRow(  "# # # ### # # #" );
		maze[5] = createRow(  "# # # # # # # #" );
		maze[6] = createRow(  "#     #   # # E" );
		maze[7] = createRow(  "# ##### # # # #" );
		maze[8] = createRow(  "#       #   # #" );
		maze[9] = createRow(  "###############" );
	}
	
	/**
	 * creates a maze by taking strings and breaking them
	 * down into a 2D array of chars.
	 */
	private static void createMaze1() {
		dim = 10;
		maze = new char[dim][];
		
		for ( int i=0; i<dim; i++ ) 
			maze[i] = new char[dim];
		
		maze[0] = createRow(  "###############" );
		maze[1] = createRow(  "              #" );
		maze[2] = createRow(  "#             #" );
		maze[3] = createRow(  "#             #" );
		maze[4] = createRow(  "#             #" );
		maze[5] = createRow(  "#             #" );
		maze[6] = createRow(  "#             #" );
		maze[7] = createRow(  "#             #" );
		maze[8] = createRow(  "E             #" );
		maze[9] = createRow(  "###############" );
	}

	/**
	 * creates a maze by taking strings and breaking them
	 * down into a 2D array of chars.
	 */
	private static void createMaze() {
		dim = 10;
		maze = new char[dim][];
		
		for ( int i=0; i<dim; i++ ) 
			maze[i] = new char[dim];
		
		maze[0] = createRow(  "###############" );
		maze[1] = createRow(  "       #      #" );
		maze[2] = createRow(  "#      #      #" );
		maze[3] = createRow(  "E      #      #" );
		maze[4] = createRow(  "#             #" );
		maze[5] = createRow(  "#             #" );
		maze[6] = createRow(  "#             #" );
		maze[7] = createRow(  "#             #" );
		maze[8] = createRow(  "#             #" );
		maze[9] = createRow(  "###############" );
	}

	/**
	 * clears the screen (works only in Terminal/Console)
	 */
	private static void clearScreen() {
        System.out.print("\033[2J\033[;H");
    }
	
	/**
	 * displays the maze, as a 2D array on screen.
	 */
	private static void displayMaze() {
		// bring cursor back to top-left (works only in Terminal/Console)
		System.out.println("\033[;H");
		
		for ( int i=0; i< maze.length; i++ ) {
			for ( int j=0; j < maze[i].length; j++ )
				System.out.print( maze[i][j] );
			System.out.println();
		}
		
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			//e.printStackTrace();
		}
	}

	
	
	/**
	 * Visit the maze.
	 */
	private static void visitMaze() {
		boolean success = recurseVisit( 1, 0 );
		if ( success ) 
			System.out.println( "Success, found a path!");
		else
			System.out.println( "No path found.");
	}

	/**
	 * recurseVisit.  Lands on cell [i,j] of the maze, and
	 * explore where to go from here, either up, down, right,
	 * or left.
	 * @param i
	 * @param j
	 * @return
	 */
	private static boolean recurseVisit(int i, int j) {
		
		// exit?
		if ( maze[i][j] == 'E' ) 
			return true;
		
		// no, put bread crumb where we landed
		maze[i][j] = '.';
		
		// display the maze in current 
		displayMaze();
		
		// look in all 4 directions around where we are...
		int newi =i, newj =j;
		for ( int dir = 0; dir < 4; dir++ ) {
			switch ( dir ) {
				case 0: newi = i-1; newj=j;   break;
				case 1: newi = i;   newj=j+1; break; 
				case 2: newi = i+1; newj=j;   break;
				case 3: newi = i;   newj=j-1; break;
			}
			
			// we are now looking in a particular direction, 1 
			// square away, at coordinates (newi, newj)  
			
			// invalid coordinates, outside the maze?
			if ( newi<0 || newj<0 
					|| newj >= maze[0].length 
					|| newi >= maze.length ) 
				continue;
			
			// the cell at (newi, newj) is empty and hasn't 
			// been visited yet?
			if ( maze[newi][newj] == ' ' || maze[newi][newj] == 'E'  ) {
				
				// YES!  We can explore going that way!
				boolean success = recurseVisit( newi, newj );
				
				// Did we find the exit going that way?
				if ( !success ) {
					// Nope... ok, let's backtrack and try another direction
					maze[newi][newj] = 'b';
					displayMaze();
				}
				else {
					// YEAH!  Found the exit that way... no
					// need to explore more... we just return
					// Mark where we are as one cell belonging
					// to the path to the Exit.
					maze[i][j] = '*';
					return true;
				}
			}
		}
		// if we're here, it's because we've explored all directions
		// we could from here, and haven't found a successful path 
		// to the exit.  So we can't go nowhere interesting from here.
		// Return false.
		return false;
	}

	/**
	 * main entry point.
	 * @param args
	 */
	public static void main(String[] args) {
		// put the maze on the screen.
		clearScreen();
		createMaze();
		displayMaze();
		
		// visit the maze
		visitMaze();
		
		// clean up the maze, remove back=tracks...
		displayMaze();
	}
}




...