Reputation: 13
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!
Upvotes: 1
Views: 273
Reputation: 86324
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?)
Upvotes: 2