|
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 are marked with different integers. |
| 7 | + * |
| 8 | + * The goal is to find a path from a starting position to the target position |
| 9 | + * (map[6][5]) while navigating through the maze. |
| 10 | + */ |
3 | 11 | public final class MazeRecursion {
|
| 12 | + |
4 | 13 | private MazeRecursion() {
|
5 | 14 | }
|
6 | 15 |
|
7 |
| - 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 |
| - |
12 |
| - // We use 1 to indicate wall |
13 |
| - // Set the ceiling and floor to 1 |
14 |
| - for (int i = 0; i < 7; i++) { |
15 |
| - map[0][i] = 1; |
16 |
| - map[7][i] = 1; |
17 |
| - } |
18 |
| - |
19 |
| - // Then we set the left and right wall to 1 |
20 |
| - for (int i = 0; i < 8; i++) { |
21 |
| - map[i][0] = 1; |
22 |
| - map[i][6] = 1; |
23 |
| - } |
24 |
| - |
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; |
30 |
| - |
31 |
| - // Print the current map |
32 |
| - System.out.println("The condition of the map: "); |
33 |
| - for (int i = 0; i < 8; i++) { |
34 |
| - for (int j = 0; j < 7; j++) { |
35 |
| - System.out.print(map[i][j] + " "); |
36 |
| - } |
37 |
| - System.out.println(); |
38 |
| - } |
39 |
| - |
40 |
| - // clone another map for setWay2 method |
41 |
| - for (int i = 0; i < map.length; i++) { |
42 |
| - System.arraycopy(map[i], 0, map2[i], 0, map[i].length); |
43 |
| - } |
44 |
| - |
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 |
50 |
| - setWay(map, 1, 1); |
51 |
| - setWay2(map2, 1, 1); |
52 |
| - |
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"); |
55 |
| - for (int i = 0; i < 8; i++) { |
56 |
| - for (int j = 0; j < 7; j++) { |
57 |
| - System.out.print(map[i][j] + " "); |
58 |
| - } |
59 |
| - System.out.println(); |
| 16 | + /** |
| 17 | + * This method solves the maze using the "down -> right -> up -> left" |
| 18 | + * movement strategy. |
| 19 | + * |
| 20 | + * @param map The 2D array representing the maze (walls, paths, etc.) |
| 21 | + * @return The solved maze with paths marked, or null if no solution exists. |
| 22 | + */ |
| 23 | + public static int[][] solveMazeUsingFirstStrategy(int[][] map) { |
| 24 | + if (setWay(map, 1, 1)) { |
| 25 | + return map; |
60 | 26 | }
|
| 27 | + return null; |
| 28 | + } |
61 | 29 |
|
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"); |
64 |
| - for (int i = 0; i < 8; i++) { |
65 |
| - for (int j = 0; j < 7; j++) { |
66 |
| - System.out.print(map2[i][j] + " "); |
67 |
| - } |
68 |
| - System.out.println(); |
| 30 | + /** |
| 31 | + * This method solves the maze using the "up -> right -> down -> left" |
| 32 | + * movement strategy. |
| 33 | + * |
| 34 | + * @param map The 2D array representing the maze (walls, paths, etc.) |
| 35 | + * @return The solved maze with paths marked, or null if no solution exists. |
| 36 | + */ |
| 37 | + public static int[][] solveMazeUsingSecondStrategy(int[][] map) { |
| 38 | + if (setWay2(map, 1, 1)) { |
| 39 | + return map; |
69 | 40 | }
|
| 41 | + return null; |
70 | 42 | }
|
71 | 43 |
|
72 | 44 | /**
|
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 |
| 45 | + * Attempts to find a path through the maze using a "down -> right -> up -> left" |
| 46 | + * movement strategy. The path is marked with '2' for valid paths and '3' for dead ends. |
84 | 47 | *
|
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 |
| 48 | + * @param map The 2D array representing the maze (walls, paths, etc.) |
| 49 | + * @param i The current x-coordinate of the ball (row index) |
| 50 | + * @param j The current y-coordinate of the ball (column index) |
| 51 | + * @return True if a path is found to (6,5), otherwise false |
91 | 52 | */
|
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 |
| 53 | + private static boolean setWay(int[][] map, int i, int j) { |
| 54 | + if (map[6][5] == 2) { |
94 | 55 | return true;
|
95 | 56 | }
|
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 |
| 57 | + |
| 58 | + // If the current position is unvisited (0), explore it |
| 59 | + if (map[i][j] == 0) { |
| 60 | + // Mark the current position as '2' |
| 61 | + map[i][j] = 2; |
| 62 | + |
| 63 | + // Move down |
| 64 | + if (setWay(map, i + 1, j)) { |
101 | 65 | return true;
|
102 |
| - } else if (setWay(map, i, j + 1)) { // go right |
| 66 | + } |
| 67 | + // Move right |
| 68 | + else if (setWay(map, i, j + 1)) { |
103 | 69 | return true;
|
104 |
| - } else if (setWay(map, i - 1, j)) { // go up |
| 70 | + } |
| 71 | + // Move up |
| 72 | + else if (setWay(map, i - 1, j)) { |
105 | 73 | return true;
|
106 |
| - } else if (setWay(map, i, j - 1)) { // go left |
| 74 | + } |
| 75 | + // Move left |
| 76 | + else if (setWay(map, i, j - 1)) { |
107 | 77 | return true;
|
108 |
| - } 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 |
112 |
| - map[i][j] = 3; |
113 |
| - return false; |
114 | 78 | }
|
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. |
| 79 | + |
| 80 | + map[i][j] = 3; // Mark as dead end (3) if no direction worked |
118 | 81 | return false;
|
119 | 82 | }
|
| 83 | + return false; |
120 | 84 | }
|
121 | 85 |
|
122 |
| - // Here is another move strategy for the ball: up->right->down->left |
123 |
| - public static boolean setWay2(int[][] map, int i, int j) { |
124 |
| - if (map[6][5] == 2) { // means the ball find its path, ending condition |
| 86 | + /** |
| 87 | + * Attempts to find a path through the maze using an alternative movement |
| 88 | + * strategy "up -> right -> down -> left". |
| 89 | + * |
| 90 | + * @param map The 2D array representing the maze (walls, paths, etc.) |
| 91 | + * @param i The current x-coordinate of the ball (row index) |
| 92 | + * @param j The current y-coordinate of the ball (column index) |
| 93 | + * @return True if a path is found to (6,5), otherwise false |
| 94 | + */ |
| 95 | + private static boolean setWay2(int[][] map, int i, int j) { |
| 96 | + if (map[6][5] == 2) { |
125 | 97 | return true;
|
126 | 98 | }
|
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 |
| 99 | + |
| 100 | + if (map[i][j] == 0) { |
| 101 | + map[i][j] = 2; |
| 102 | + |
| 103 | + // Move up |
| 104 | + if (setWay2(map, i - 1, j)) { |
132 | 105 | return true;
|
133 |
| - } else if (setWay2(map, i, j + 1)) { // go right |
| 106 | + } |
| 107 | + // Move right |
| 108 | + else if (setWay2(map, i, j + 1)) { |
134 | 109 | return true;
|
135 |
| - } else if (setWay2(map, i + 1, j)) { // go down |
| 110 | + } |
| 111 | + // Move down |
| 112 | + else if (setWay2(map, i + 1, j)) { |
136 | 113 | return true;
|
137 |
| - } else if (setWay2(map, i, j - 1)) { // go left |
| 114 | + } |
| 115 | + // Move left |
| 116 | + else if (setWay2(map, i, j - 1)) { |
138 | 117 | return true;
|
139 |
| - } 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 |
143 |
| - map[i][j] = 3; |
144 |
| - return false; |
145 | 118 | }
|
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. |
| 119 | + |
| 120 | + map[i][j] = 3; // Mark as dead end (3) if no direction worked |
149 | 121 | return false;
|
150 | 122 | }
|
| 123 | + return false; |
151 | 124 | }
|
152 | 125 | }
|
0 commit comments