-
Notifications
You must be signed in to change notification settings - Fork 0
/
Maze.java
215 lines (156 loc) · 6.61 KB
/
Maze.java
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package Recursion.Maze;
import java.io.*;
public class Maze {
/**
* This class aims to find a solution to a maze.
*
* @author Michael Zhou
* @course COSC 1P03
* @assignment #4 (Part 2)
* @version 1.0
* @date 2022-03-23
*/
// private ASCIIDataFile dataFile;
// private ASCIIOutputFile outputFile;
private PrintWriter outputFile;
private BufferedReader dataFile;
private char[][] field; // maze
private char[][] solution; // solution to the maze
int startX; // starting coordinates
int startY;
public Maze() throws IOException {
// read from data file to array
// clear the solution file first
File f = new File("./src/Recursion/Maze/Solution.txt");
f.delete();
outputFile = new PrintWriter(new FileOutputStream("./src/Recursion/Maze/Solution.txt", true));
// dataFile = new BufferedReader(new FileReader("./src/Recursion/Maze/smol Maze.txt"));
dataFile = new BufferedReader(new FileReader("./src/Recursion/Maze/big chungus maze.txt"));
// dataFile = new BufferedReader(new FileReader("./src/Recursion/Maze/no solution maze.txt"));
String[] thing = dataFile.readLine().split("\t");
field = new char[Integer.parseInt(thing[0])][Integer.parseInt(thing[1])];
for (int i = 0; i < field.length; i++ ) {
char[] readValue = dataFile.readLine().toCharArray();
for (int j = 0; j < field[i].length; j++) {
field[i][j] = readValue[j];
}
}
// generate a random, valid (ignoring walls) start position
for (;;) {
startX = (int) Math.floor(Math.random() * (field.length - 1) + 1); // assume outer wall of maze will be solid, ignore outer border when generating numbers
startY = (int) Math.floor(Math.random() * (field.length - 1) + 1);
if (field[startX][startY] == ' ') {
field[startX][startY] = 'S';
break;
}
}
display(field); // print original map to console
/** Manual start pos override */
// startX = 34;
// startY = 50;
// field[startX][startY] = 'S';
System.out.println("\n\n\n-----------------\nProcessing...\n-----------------");
findPath(startX, startY, field);
findPath(startX, startY, copyArray(field));
System.out.println("\n\n\n-----------------\nPrinting solution\n-----------------");
// outputFile = new ASCIIOutputFile();
try { // differentiate between no solution and valid solution
display(solution);
save(solution);
}
catch (Exception error) {
System.out.println("No solution");
outputFile.println("No solution");
}
dataFile.close();
outputFile.close();
}
private void findPath (int row, int column, char[][] maze) {
/**
* This method is the pathfinding of the maze.
*
* @param row position in the row
* @param column position in the column
* @param maze The current maze with the most progress in finding the end.
*/
if (maze[row][column] == 'E') {
maze[startX][startY] = 'S'; // compensate for destruction of start marker during pathfinding
solution = copyArray(maze); // This is my way to return a maze once a solution has reached without forcefully stopping the recursion
// throw new RuntimeException(); // prevent unnecessary recursion
return;
/** The solution is found. Let's ignore the fact that solutions can be potentially extremely inefficient. The guidelines say it's ok ¯\_(ツ)_/¯ */
}
if (maze[row][column] == '#' || maze[row][column] == '.' || maze[row][column] == '>'|| maze[row][column] == 'v'|| maze[row][column] == '<'|| maze[row][column] == '^') {
// treat directional markers as walls or "clockwise loop of death"
return;
}
// try all 4 directions
maze[row][column] = '>'; findPath(row,column +1, maze);
maze[row][column] = 'v'; findPath(row+1,column, maze);
maze[row][column] = '<'; findPath(row,column -1, maze);
maze[row][column] = '^'; findPath(row-1,column, maze);
maze[row][column] = '.'; // all possibilities exhausted
}
private char[][] copyArray(char[][] array) {
/**
* Create a copy of a char array
*
* @param array Char array to be copied
* @return copy of char[][] array
*/
char[][] newArray = new char[array.length][array[0]. length]; // use static value 0 because we wil only work with non-raggad
for (int i = 0; i < field.length; i++ ) {
for (int j = 0; j < field[i].length; j++) {
newArray[i][j] = array[i][j];
}
}
return newArray;
}
private void display(char[][]array) {
/**
* This method displays the field array to console. Assume array is valid with no holes
*
* @param array Char array to be displayed
*/
for (int i = 0; i < array.length; i++ ) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]);
}
System.out.print("\n");
}
}
private void save(char[][]array) {
/**
* This method writes field to file. Assume array is valid with no holes
*
* @param array Char array to be written
*/
for (int i = 0; i < array.length; i++ ) {
for (int j = 0; j < array[i].length; j++) {
outputFile.print(array[i][j]);
}
outputFile.println();
}
}
private char[][] focusOnRoute(char[][] array) {
/**
* Eliminate the '.' for better viewing of solution. This isn't really part of the assignment
*
* @param array Char array to be processed
* @return copy of processed array
*/
char[][] newArray = new char[array.length][array[0]. length]; // use static value 0 because we wil only work with non-ragged
for (int i = 0; i < array.length; i++ ) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] == '.') {
newArray[i][j] = ' ';
}
else {
newArray[i][j] = array[i][j];
}
}
}
return array;
}
public static void main ( String[] args ) throws IOException { Maze i = new Maze(); };
}