-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMaze.java
More file actions
109 lines (100 loc) · 3.35 KB
/
Maze.java
File metadata and controls
109 lines (100 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Author: Lucas Ryan
* FileName: Maze.java
* Date: July 31, 2016
* NID: lu469191
*/
import java.util.ArrayDeque;
import java.util.Queue;
// wrapper class to keep hold of row, column, and value at cell
class Point {
int row;
int col;
int val;
public Point(int r, int c, int v) {
row = r;
col = c;
val = v;
}
}
public class Maze {
// associated array to keep track of moves to get there
static int[][] assocMaze;
// 2D array to store possible moves can make
final static int[][] MOVE_SET = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
// implement a BFS to find the shortest path from
// start to end. expect we don't have a null array
public static void solve(char[][] maze) throws Exception {
// if maze has either 1 row or 1 column, then our start is the end so return maze
if (3 < maze.length || 3 < maze[0].length) {
assocMaze = new int[maze.length][maze[0].length];
// going to be used to implement BFS traversal of maze
Queue<Point> queue = new ArrayDeque<Point>();
// add starting point of maze
queue.add(new Point(1, 1, 1));
// continue until find end of maze
while (!queue.isEmpty()) {
// get the next node
Point p = queue.remove();
// search through the possible moves we can make
for (int i = 0; i < MOVE_SET.length; i++) {
// get the neighboring cell
int nextRow = p.row + MOVE_SET[i][0];
int nextCol = p.col + MOVE_SET[i][1];
// skip over if back at beginning of maze
if (nextRow == 1 && nextCol == 1) continue;
// mark the move if not a wall and haven't been there yet
if (maze[nextRow][nextCol] != '#' && assocMaze[nextRow][nextCol] == 0) {
// mark the distance to get there
assocMaze[nextRow][nextCol] = p.val + 1;
// add to queue to look at its kids
queue.add(new Point(nextRow, nextCol, p.val + 1));
}
}
}
maze = makeMaze(maze);
}
}
// use the assocMaze to mark the shortest path from start to end
private static char[][] makeMaze(char[][] maze) {
// flag to mark if we have completed the path
boolean isComplete = false;
// going to start at end of maze
int currRow = maze.length - 2;
int currCol = maze[0].length - 2;
// we will be working our way back, end to start
while (!isComplete) {
// check all possible directions could have came from
// we can break out of the loop once we find the one
// neighbor cell we are looking for, since only one
// possible cell could have came from
for (int i = 0; i < MOVE_SET.length; i++) {
int nextRow = currRow + MOVE_SET[i][0];
int nextCol = currCol + MOVE_SET[i][1];
// set flag if reached the start point
if (nextRow == 1 && nextCol == 1) {
isComplete = true;
break;
}
// look at neighboring cells and select the one we came from
// which will be the one that is 1 less than current distance
// from start point
else if (maze[nextRow][nextCol] != '#' &&
(assocMaze[nextRow][nextCol] - assocMaze[currRow][currCol] == -1)) {
// mark cell as taken
maze[nextRow][nextCol] = '.';
// update to cell at
currRow = nextRow;
currCol = nextCol;
break;
}
}
}
// return modified maze
return maze;
}
// return true when the maze cell is a valid location and not a wall
private static boolean isValidMove(int row, int col, char[][] maze) {
return (maze[row][col] != '#');
}
}