Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.*;
- public class Maze {
- private final static int DIRECTION_UP = 0;
- private final static int DIRECTION_RIGHT = 1;
- private final static int DIRECTION_DOWN = 2;
- private final static int DIRECTION_LEFT = 3;
- public final int corner = 1;
- public final int hWall = 4;
- public final int vWall = 3;
- public final int empty = 0;
- public final int blind = -1;
- public final int path = 2;
- private int width;
- private int height;
- private MazePoint[][] matrix;
- public int[][] maze;
- /*
- * constructor, initial width, height and matrix
- */
- public Maze(int width, int height) {
- this.width = width;
- this.height = height;
- this.matrix = new MazePoint[height][width];
- for (int i=0; i<height; i++)
- for (int j=0; j<width; j++)
- matrix[i][j] = new MazePoint();
- this.maze = new int[2*height+1][2*width+1];
- }
- /*
- * check if the target neighbor can be visited
- */
- public boolean checkNeighbor(int x, int y, int dir) {
- boolean neighborVisited = false;
- switch ( dir ) {
- case DIRECTION_UP:
- if ( x <= 0 )
- neighborVisited = true;
- else
- neighborVisited = matrix[x-1][y].visited();
- break;
- case DIRECTION_RIGHT:
- if ( y >= width - 1 )
- neighborVisited = true;
- else
- neighborVisited = matrix[x][y+1].visited();
- break;
- case DIRECTION_DOWN:
- if ( x >= height - 1 )
- neighborVisited = true;
- else
- neighborVisited = matrix[x+1][y].visited();
- break;
- case DIRECTION_LEFT:
- if ( y <= 0 )
- neighborVisited = true;
- else
- neighborVisited = matrix[x][y-1].visited();
- break;
- }
- return !neighborVisited;
- }
- /*
- * check if the neighbors have at least one non-visited point
- */
- public boolean checkNeighbor(int x, int y) {
- return (this.checkNeighbor(x, y, DIRECTION_UP) ||
- this.checkNeighbor(x, y, DIRECTION_RIGHT) ||
- this.checkNeighbor(x, y, DIRECTION_DOWN) ||
- this.checkNeighbor(x, y, DIRECTION_LEFT));
- }
- /*
- * pick up a random traversal direction
- */
- public int getRandDirection(int x, int y) {
- int dir = -1;
- Random rand = new Random();
- if ( checkNeighbor(x, y) ) {
- do {
- dir = rand.nextInt(4);
- } while ( !checkNeighbor(x, y, dir) );
- }
- return dir;
- }
- /*
- * push down the wall between the adjacent two points
- */
- public void pushWall(int x, int y, int dir) {
- switch ( dir ) {
- case DIRECTION_UP:
- matrix[x][y].setTop(false);
- matrix[x-1][y].setBottom(false);
- break;
- case DIRECTION_RIGHT:
- matrix[x][y].setRight(false);
- matrix[x][y+1].setLeft(false);
- break;
- case DIRECTION_DOWN:
- matrix[x][y].setBottom(false);
- matrix[x+1][y].setTop(false);
- break;
- case DIRECTION_LEFT:
- matrix[x][y].setLeft(false);
- matrix[x][y-1].setRight(false);
- break;
- }
- }
- /*
- * depth first search traversal
- */
- public void traversal() {
- int x = 0;
- int y = 0;
- Stack<Integer> stackX = new Stack<Integer>();
- Stack<Integer> stackY = new Stack<Integer>();
- do {
- MazePoint p = matrix[x][y];
- if ( !p.visited() ) {
- p.setVisited(true);
- }
- if ( checkNeighbor(x, y) ) {
- int dir = this.getRandDirection(x, y);
- this.pushWall(x, y, dir);
- stackX.add(x);
- stackY.add(y);
- switch ( dir ) {
- case DIRECTION_UP:
- x--;
- break;
- case DIRECTION_RIGHT:
- y++;
- break;
- case DIRECTION_DOWN:
- x++;
- break;
- case DIRECTION_LEFT:
- y--;
- break;
- }
- }
- else {
- x = stackX.pop();
- y = stackY.pop();
- }
- } while ( !stackX.isEmpty() );
- }
- public void contributeMaze() {
- for (int j=0; j<2*width+1; j++)
- { if (j%2 == 0)
- maze[0][j] = corner;
- else
- maze[0][j] = hWall;
- }
- for (int i=0; i<height; i++) {
- maze[2*i+1][0] = vWall;
- for (int j=0; j<width; j++) {
- maze[2*i+1][2*j+1] = empty;
- if ( matrix[i][j].isRight() )
- maze[2*i+1][2*j+2] = vWall;
- else
- maze[2*i+1][2*j+2] = empty;
- }
- maze[2*i+2][0] = 1;
- for (int j=0; j<width; j++) {
- if ( matrix[i][j].isBottom() )
- maze[2*i+2][2*j+1] = 4;
- else
- maze[2*i+2][2*j+1] = empty;
- maze[2*i+2][2*j+2] = corner;
- }
- }
- maze[0][1] = empty;
- maze[2*width][2*height-1] = empty;
- }
- /*
- * print the matrix
- */
- public void print() {
- for (int i=0; i<2*height+1; i++) {
- for (int j=0; j<2*width+1; j++)
- if ( maze[i][j] == corner )
- System.out.print("+");
- else if ( maze[i][j] == vWall )
- System.out.print("|");
- else if ( maze[i][j] == hWall )
- System.out.print("-");
- else if ( maze[i][j] == path )
- System.out.print("#");
- else
- System.out.print(" ");
- System.out.println();
- }
- }
- public void printOrder() {
- for (int i=0; i<2*height+1; i++) {
- for (int j=0; j<2*width+1; j++)
- if ( maze[i][j] == corner )
- System.out.print("+");
- else if ( maze[i][j] == vWall )
- System.out.print("|");
- else if ( maze[i][j] == hWall )
- System.out.print("-");
- else if ( maze[i][j] == path )
- System.out.print(i);
- else
- System.out.print(" ");
- System.out.println();
- }
- }
- public int getBreakOutDir(int x, int y) {
- int dir = -1;
- if ( maze[x][y+1] == 0 )
- dir = DIRECTION_RIGHT;
- else if ( maze[x+1][y] == 0 )
- dir = DIRECTION_DOWN;
- else if ( maze[x][y-1] == 0 )
- dir = DIRECTION_LEFT;
- else if ( maze[x-1][y] == 0 )
- dir = DIRECTION_UP;
- return dir;
- }
- /*
- * find the path from (1, 1) to (2*height-1, 2*width-1)
- */
- public void findPathDFS() {
- int x = 1;
- int y = 1;
- Stack<Integer> stackX = new Stack<Integer>();
- Stack<Integer> stackY = new Stack<Integer>();
- do {
- int dir = this.getBreakOutDir(x, y);
- if ( dir == -1 ) {
- maze[x][y] = blind;
- x = stackX.pop();
- y = stackY.pop();
- }
- else {
- maze[x][y] = path;
- stackX.add(x);
- stackY.add(y);
- switch ( dir ) {
- case DIRECTION_UP:
- x--;
- break;
- case DIRECTION_RIGHT:
- y++;
- break;
- case DIRECTION_DOWN:
- x++;
- break;
- case DIRECTION_LEFT:
- y--;
- break;
- }
- }
- }
- while ( !(x == 2*height-1 && y == 2*width-1) );
- maze[x][y] = path;
- }
- public void findPathBFS() {
- int x = 1;
- int y = 1;
- Queue<Integer> queueX = new LinkedList<Integer>();
- Queue<Integer> queueY = new LinkedList<Integer>();
- do {
- int dir = this.getBreakOutDir(x, y);
- if ( dir == -1 ) {
- maze[x][y] = blind;
- x = queueX.poll();
- y = queueY.poll();
- }
- else {
- maze[x][y] = path;
- queueX.add(x);
- queueY.add(y);
- switch ( dir ) {
- case DIRECTION_UP:
- x--;
- break;
- case DIRECTION_RIGHT:
- y++;
- break;
- case DIRECTION_DOWN:
- x++;
- break;
- case DIRECTION_LEFT:
- y--;
- break;
- }
- }
- } while ( !(x == 2*height-1 && y == 2*width-1) );
- maze[x][y] = path;
- }
- public void reset() {
- for (int i=0; i<2*height+1; i++)
- for (int j=0; j<2*width+1; j++)
- if ( maze[i][j] == path )
- maze[i][j] = empty;
- }
- public static void main(String[] args) {
- Maze maze = new Maze(4, 4);
- maze.traversal();
- maze.contributeMaze();
- System.out.println("Create new map");
- maze.print();
- maze.findPathDFS();
- System.out.println("Find DFS Solution");
- maze.print();
- maze.printOrder();
- maze.reset();
- System.out.println("Reset to new map");
- maze.print();
- maze.findPathBFS();
- System.out.println("Find BFS Solution");
- maze.print();
- maze.printOrder();
- }
- public int getRandDirectionJUnits(int x, int y) {
- int dir = -1;
- Random rand = new Random(0);
- if ( checkNeighbor(x, y) ) {
- do {
- dir = rand.nextInt(4);
- } while ( !checkNeighbor(x, y, dir) );
- }
- return dir;
- }
- public void traversalJUnits() {
- int x = 0;
- int y = 0;
- Stack<Integer> stackX = new Stack<Integer>();
- Stack<Integer> stackY = new Stack<Integer>();
- do {
- MazePoint mp = matrix[x][y];
- if ( !mp.visited() ) {
- mp.setVisited(true);
- }
- if ( checkNeighbor(x, y) ) {
- int dir = this.getRandDirectionJUnits(x, y);
- this.pushWall(x, y, dir);
- stackX.add(x);
- stackY.add(y);
- switch ( dir ) {
- case DIRECTION_UP:
- x--;
- break;
- case DIRECTION_RIGHT:
- y++;
- break;
- case DIRECTION_DOWN:
- x++;
- break;
- case DIRECTION_LEFT:
- y--;
- break;
- }
- }
- else {
- x = stackX.pop();
- y = stackY.pop();
- }
- } while ( !stackX.isEmpty() );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement