Skip to content
Advertisement

Simple text maze solver that starts from middle point doesn’t end when finding first exit

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?)

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement