I searched for a problem close to mine but every maze has some starting or finishing points or starts from the edge of the maze. I want to find the first exit possible starting from the middle of teh maze and print the maze with the route to the exit. For example I have maze like this:
XXX XXXXXX XX XXX XX XX XXX XX XX XX XXX X XXX XXXX XXXXX
And we start from the middle point:
XXX XXXXXX XX XXX XX XX XXX XX XX XX* XXX X XXX XXXX XXXXX
Then I think that the exit should be like this:
XXX XXXXXX XX XXX XX XX XXX XX XX XX* XXX X ** XXX XXXX*XXXXX
But instead I get something like this:
XXX XXXXXX XX**XXX XX XX*XXX XX XX*XX* XXX X **** XXX XXXX*XXXXX
Also If I input bigger maze for example:
XXX XX X X X X XX XX X X XXX X X XX XX XX X X X X X X XX X XXXX XXX XX XX XX
I get this error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 7 at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48) at java.base/java.lang.String.charAt(String.java:712) at Labyrinth.initializeMaze(Labyrinth.java:37) at Start.main(Start.java:3)
And I don’t really know what the problem is. My code looks like this.
Start.java(starting class)
public class Start { public static void main(String[] args) { Labyrinth.initializeMaze("simplemaze.txt"); Labyrinth.printMaze(); if (Labyrinth.solveMaze(Labyrinth.startrow, Labyrinth.startcol)) Labyrinth.printMaze(); else System.out.println("Unsolvable"); } }
Labyrinth.java(solving class)
import java.util.ArrayList; import java.util.Scanner; import java.io.*; public class Labyrinth { private static char [][] maze; static int startrow; static int startcol; private static ArrayList<String> mazeBuffer; public static void initializeMaze (String fileName) { startrow = startcol = -1; mazeBuffer = new ArrayList<String>(); int numcols = 0; try { Scanner file = new Scanner (new File(fileName)); while(file.hasNext()) { String nextLine = file.nextLine(); mazeBuffer.add(nextLine); if (nextLine.length() > numcols) numcols = nextLine.length(); } } catch(Exception e){ System.out.println(fileName + " has an issue"); } int numrows = mazeBuffer.size(); System.out.println(numrows); System.out.println(numcols); maze = new char[numrows][numcols]; for (int r = 0; r < numrows; r++){ String row = mazeBuffer.get(r); for (int c = 0; c < numcols; c++){ if (row.length() >= c) maze[r][c] = row.charAt(c); else maze[r][c] = 'X'; if (r==numrows/2 && c==numcols/2 && row.length() >= c){ startrow = r; startcol = c; } } } System.out.println("Maze loaded"); } public static void printMaze(){ for (char[] row: maze){ for (char c: row) System.out.print(c); System.out.println(); } System.out.println(); } public static boolean solveMaze(int r, int c){ if (r < 0 || c < 0 || r >= maze.length || c >= maze[0].length) return false; if (maze[r][c] == ' ' && r == mazeBuffer.size() || maze[r][c] == ' ' && r == 0 || maze[r][c] == ' ' && c==0 || maze[r][c] == ' ' && c==10) return true; if (maze[r][c] != ' ' && maze[r][c] != 'S') return false; maze[r][c] = '*'; if (solveMaze(r-1,c)){ maze[r][c] = '*'; return true; } if (solveMaze(r+1,c)){ maze[r][c] = '*'; return true; } if (solveMaze(r,c-1)){ maze[r][c] = '*'; return true; } if (solveMaze(r,c+1)){ maze[r][c] = '*'; return true; } return false; } }
I modified it because at the start the program would get from point S(start) to point F(finish), but I want it to print the maze with first found route to exit without using any obvious points in the maze file itself. Any help would be greatly appreciated!
Advertisement
Answer
In your observed output you notice the asterisk in the bottom row.
XXXX*XXXXX
So your solver has made it this far. But apparently has not discovered that there’s an exit here and hence has continued searching.
The problem is in this line:
if (maze[r][c] == ' ' && r == mazeBuffer.size() || maze[r][c] == ' ' && r == 0 || maze[r][c] == ' ' && c==0 || maze[r][c] == ' ' && c==10)
mazeBuffer
has size 6 and the rows are indexed 0 through 5. So when r
is 5 and pointing to the last row, it is not equal to the size, and solveMaze()
does not return true on this occasion. Instead it keeps searching until it find an exit to the top or left.
Instead you probably want:
if (maze[r][c] == ' ' && r == mazeBuffer.size() - 1 || maze[r][c] == ' ' && r == 0 || maze[r][c] == ' ' && c==0 || maze[r][c] == ' ' && c == maze[r].length - 1)
Now the output is:
XXX XXXXXX XX XXX XX XX XXX XX XX XX* XXX X ** XXX XXXX XXXXX
Your method never prints the asterisk at the exit where it exits. I am leaving it to you to fix that detail.
Furthermore I believe that I was right in my comment:
Before returning false you should probably set
maze[r][c]
back to whichever value it had before (would that be' '
always?)