1
1
package com .thealgorithms .backtracking ;
2
2
3
+ /**
4
+ * This class contains methods to solve a maze using recursive backtracking.
5
+ * The maze is represented as a 2D array where walls, paths, and visited/dead
6
+ * ends
7
+ * are marked with different integers.
8
+ *
9
+ * The goal is to find a path from a starting position to the target position
10
+ * (map[6][5]) while navigating through the maze.
11
+ */
3
12
public final class MazeRecursion {
13
+
4
14
private MazeRecursion () {
5
15
}
6
16
17
+ /**
18
+ * This method sets up a maze as a 2D array, where '1' represents walls and '0'
19
+ * represents open paths. It then calls recursive functions to find paths using
20
+ * two different movement strategies. The results are printed to the console.
21
+ */
7
22
public static void mazeRecursion () {
8
- // First create a 2 dimensions array to mimic a maze map
9
- int [][] map = new int [8 ][7 ];
10
- int [][] map2 = new int [8 ][7 ];
11
23
12
- // We use 1 to indicate wall
13
- // Set the ceiling and floor to 1
24
+ int [][] map = new int [8 ][7 ]; // Create an 8x7 maze map (2D array)
25
+ int [][] map2 = new int [8 ][7 ]; // Copy of the maze for an alternative pathfinding method
26
+
27
+ // Initialize the maze with boundaries (set walls as '1')
28
+ // Set the top and bottom rows as walls
14
29
for (int i = 0 ; i < 7 ; i ++) {
15
30
map [0 ][i ] = 1 ;
16
31
map [7 ][i ] = 1 ;
17
32
}
18
33
19
- // Then we set the left and right wall to 1
34
+ // Set the left and right columns as walls
20
35
for (int i = 0 ; i < 8 ; i ++) {
21
36
map [i ][0 ] = 1 ;
22
37
map [i ][6 ] = 1 ;
23
38
}
24
39
25
- // Now we have created a maze with its wall initialized
26
-
27
- // Here we set the obstacle
28
- map [3 ][1 ] = 1 ;
29
- map [3 ][2 ] = 1 ;
40
+ // Place internal obstacles in the maze
41
+ map [3 ][1 ] = 1 ; // Wall block at position (3,1)
42
+ map [3 ][2 ] = 1 ; // Wall block at position (3,2)
30
43
31
- // Print the current map
32
- System .out .println ("The condition of the map: " );
44
+ System .out .println ("Initial maze layout:" );
33
45
for (int i = 0 ; i < 8 ; i ++) {
34
46
for (int j = 0 ; j < 7 ; j ++) {
35
47
System .out .print (map [i ][j ] + " " );
36
48
}
37
49
System .out .println ();
38
50
}
39
51
40
- // clone another map for setWay2 method
52
+ // Clone the maze into map2 for the second pathfinding method
41
53
for (int i = 0 ; i < map .length ; i ++) {
42
54
System .arraycopy (map [i ], 0 , map2 [i ], 0 , map [i ].length );
43
55
}
44
56
45
- // By using recursive backtracking to let your ball(target) find its way in the
46
- // maze
47
- // The first parameter is the map
48
- // Second parameter is x coordinate of your target
49
- // Third parameter is the y coordinate of your target
57
+ // Use the first pathfinding method with a "down -> right -> up -> left" strategy
50
58
setWay (map , 1 , 1 );
59
+
60
+ // Use the second pathfinding method with a "up -> right -> down -> left" strategy
51
61
setWay2 (map2 , 1 , 1 );
52
62
53
- // Print out the new map1, with the ball footprint
54
- System .out .println ("After the ball goes through the map1,show the current map1 condition " );
63
+ // Print the maze after pathfinding using the first method
64
+ System .out .println ("Maze after pathfinding using first strategy: " );
55
65
for (int i = 0 ; i < 8 ; i ++) {
56
66
for (int j = 0 ; j < 7 ; j ++) {
57
67
System .out .print (map [i ][j ] + " " );
58
68
}
59
69
System .out .println ();
60
70
}
61
71
62
- // Print out the new map2, with the ball footprint
63
- System .out .println ("After the ball goes through the map2,show the current map2 condition " );
72
+ // Print the maze after pathfinding using the second method
73
+ System .out .println ("Maze after pathfinding using second strategy: " );
64
74
for (int i = 0 ; i < 8 ; i ++) {
65
75
for (int j = 0 ; j < 7 ; j ++) {
66
76
System .out .print (map2 [i ][j ] + " " );
@@ -70,82 +80,97 @@ public static void mazeRecursion() {
70
80
}
71
81
72
82
/**
73
- * Using recursive path finding to help the ball find its way in the maze
74
- * Description:
75
- * 1. map (means the maze)
76
- * 2. i, j (means the initial coordinate of the ball in the maze)
77
- * 3. if the ball can reach the end of maze, that is position of map[6][5],
78
- * means the we have found a path for the ball
79
- * 4. Additional Information: 0 in the map[i][j] means the ball has not gone
80
- * through this position, 1 means the wall, 2 means the path is feasible, 3
81
- * means the ball has gone through the path but this path is dead end
82
- * 5. We will need strategy for the ball to pass through the maze for example:
83
- * Down -> Right -> Up -> Left, if the path doesn't work, then backtrack
83
+ * Attempts to find a path through the maze using a "down -> right -> up ->
84
+ * left" movement strategy. The ball tries to reach position (6,5), and the path is
85
+ * marked with '2' for valid paths and '3' for dead ends.
84
86
*
85
- * @author OngLipWei
86
- * @version Jun 23, 2021 11:36:14 AM
87
- * @param map The maze
88
- * @param i x coordinate of your ball(target)
89
- * @param j y coordinate of your ball(target)
90
- * @return If we did find a path for the ball,return true,else false
87
+ * @param map The 2D array representing the maze (walls, paths, etc.)
88
+ * @param i The current x-coordinate of the ball (row index)
89
+ * @param j The current y-coordinate of the ball (column index)
90
+ * @return True if a path is found to (6,5), otherwise false
91
91
*/
92
92
public static boolean setWay (int [][] map , int i , int j ) {
93
- if (map [6 ][5 ] == 2 ) { // means the ball find its path, ending condition
93
+ if (map [6 ][5 ] == 2 ) {
94
94
return true ;
95
95
}
96
- if (map [i ][j ] == 0 ) { // if the ball haven't gone through this point
97
- // then the ball follows the move strategy : down -> right -> up -> left
98
- map [i ][j ] = 2 ; // we assume that this path is feasible first, set the current point to 2
99
- // first。
100
- if (setWay (map , i + 1 , j )) { // go down
96
+
97
+ // If the current position is unvisited (0), explore it
98
+ if (map [i ][j ] == 0 ) {
99
+ // Assume the path is feasible, mark the current position as '2'
100
+ map [i ][j ] = 2 ;
101
+
102
+ // Try moving down
103
+ if (setWay (map , i + 1 , j )) {
101
104
return true ;
102
- } else if (setWay (map , i , j + 1 )) { // go right
105
+ }
106
+ // Try moving right
107
+ else if (setWay (map , i , j + 1 )) {
103
108
return true ;
104
- } else if (setWay (map , i - 1 , j )) { // go up
109
+ }
110
+ // Try moving up
111
+ else if (setWay (map , i - 1 , j )) {
105
112
return true ;
106
- } else if (setWay (map , i , j - 1 )) { // go left
113
+ }
114
+ // Try moving left
115
+ else if (setWay (map , i , j - 1 )) {
107
116
return true ;
108
117
} else {
109
- // means that the current point is the dead end, the ball cannot proceed, set
110
- // the current point to 3 and return false, the backtracking will start, it will
111
- // go to the previous step and check for feasible path again
118
+ // Mark the current position as a dead end (3) and backtrack
112
119
map [i ][j ] = 3 ;
113
120
return false ;
114
121
}
115
- } else { // if the map[i][j] != 0 , it will probably be 1,2,3, return false because the
116
- // ball cannot hit the wall, cannot go to the path that has gone though before,
117
- // and cannot head to deadened.
122
+ } else {
123
+ // If the position is not unvisited (either a wall, dead end, or already part of
124
+ // the path), return false
118
125
return false ;
119
126
}
120
127
}
121
128
122
- // Here is another move strategy for the ball: up->right->down->left
129
+ /**
130
+ * Attempts to find a path through the maze using an alternative movement
131
+ * strategy "up -> right -> down -> left".
132
+ * This method explores a different order of
133
+ * movement compared to setWay().
134
+ *
135
+ * @param map The 2D array representing the maze (walls, paths, etc.)
136
+ * @param i The current x-coordinate of the ball (row index)
137
+ * @param j The current y-coordinate of the ball (column index)
138
+ * @return True if a path is found to (6,5), otherwise false
139
+ */
123
140
public static boolean setWay2 (int [][] map , int i , int j ) {
124
- if (map [6 ][5 ] == 2 ) { // means the ball find its path, ending condition
125
- return true ;
141
+ // Check if the ball has reached the target at map[6][5]
142
+ if (map [6 ][5 ] == 2 ) {
143
+ return true ; // Path found
126
144
}
127
- if (map [i ][j ] == 0 ) { // if the ball haven't gone through this point
128
- // then the ball follows the move strategy : up->right->down->left
129
- map [i ][j ] = 2 ; // we assume that this path is feasible first, set the current point to 2
130
- // first。
131
- if (setWay2 (map , i - 1 , j )) { // go up
145
+
146
+ // If the current position is unvisited (0), explore it
147
+ if (map [i ][j ] == 0 ) {
148
+ // Assume the path is feasible, mark the current position as '2'
149
+ map [i ][j ] = 2 ;
150
+
151
+ // Try moving up
152
+ if (setWay2 (map , i - 1 , j )) {
132
153
return true ;
133
- } else if (setWay2 (map , i , j + 1 )) { // go right
154
+ }
155
+ // Try moving right
156
+ else if (setWay2 (map , i , j + 1 )) {
134
157
return true ;
135
- } else if (setWay2 (map , i + 1 , j )) { // go down
158
+ }
159
+ // Try moving down
160
+ else if (setWay2 (map , i + 1 , j )) {
136
161
return true ;
137
- } else if (setWay2 (map , i , j - 1 )) { // go left
162
+ }
163
+ // Try moving left
164
+ else if (setWay2 (map , i , j - 1 )) {
138
165
return true ;
139
166
} else {
140
- // means that the current point is the dead end, the ball cannot proceed, set
141
- // the current point to 3 and return false, the backtracking will start, it will
142
- // go to the previous step and check for feasible path again
167
+ // Mark the current position as a dead end (3) and backtrack
143
168
map [i ][j ] = 3 ;
144
169
return false ;
145
170
}
146
- } else { // if the map[i][j] != 0 , it will probably be 1,2,3, return false because the
147
- // ball cannot hit the wall, cannot go to the path that has gone through before,
148
- // and cannot head to deadend.
171
+ } else {
172
+ // If the position is not unvisited (either a wall, dead end, or already part of
173
+ // the path), return false
149
174
return false ;
150
175
}
151
176
}
0 commit comments