-4

Currently I am trying to solve a program that determines whether it is possible to solve a maze and if the maze is solvable it should print out the number of steps to go through the maze path. The starting position and the end position and the maze are given in a input file in the following format:

Line 1: test cases(N)

For each N lines the first line will contain size of the maze, the start position and the end exit location will be given. Then a visual depiction of the maze will also be present in the input file

For example the sample input for this challenge is:

3
6 7 0 0 5 6
1110111
1011101
1001001
1011101
1000001
1111110
3 3 2 0 0 2
111
110
111
5 5 1 0 3 1
01111
11001
01001
01001
01111

The excact rules of the maze are that the 0s are inpenetrable walls and the 1s are free walking space being able to move around. Also the end position is not marked by any special character but rather the location is given to us.

The following code is my approach to the challenge which is obviously not functional:

import java.io.*;
import java.util.*;
public class Maze
{

    public static void main(String[] args) throws FileNotFoundException
    {
        Scanner sc = new Scanner(new File("maze.txt"));
        int tc = sc.nextInt();
        for(int p  = 0; p < tc; p++ ) {
            int rows = sc.nextInt();
            int cols = sc.nextInt();
            int startRow = sc.nextInt();
            int startCol = sc.nextInt();
            int endRow = sc.nextInt();
            int endCol = sc.nextInt();
            sc.nextLine();
            char[][] maze = new char[rows][cols];
            for(int i = 0; i < rows; i++) {
                String s = sc.nextLine();
                for(int j = 0; j < cols; j++) {
                    maze[i][j] = s.charAt(j);
                }
            }

            if(solvable(maze,startRow,startCol,endCol,endRow)) {
                int count = 0;
                for(char[] arr : maze) {
                    for(char elem: arr) {
                        if(elem == 'x') count++;
                    }
                }
                System.out.println("It takes " + count + " steps to solve the maze");
            }else {
                System.out.println("Unsolvable");
            }


        }

    }


    public static boolean solvable(char[][] maze,int row, int col,int finishRow, int finishCol) {

        if(row < 0 || col < 0 || row >maze.length - 1 || col > maze[0].length - 1) {
            return false;
        }
        if(row == finishRow && col == finishCol) {
            return true;
        }
        if(maze[row][col] == 0) {
            return false;
        }
        char c = maze[row][col];
        maze[row][col] = 'x';
        if(solvable(maze,row + 1,col,finishRow,finishCol)) {
            return true;
        }
        if(solvable(maze,row - 1,col,finishRow,finishCol)){
            return true;
        }
        if(solvable(maze,row ,col + 1,finishRow,finishCol)) {
            return true;
        }
        if(solvable(maze,row,col - 1,finishRow,finishCol)) {
            return true;
        }
        maze[row][col] = c;
        return false;


    }

}

As seen by the title this program produces a stack overflow error. I am incorporating the general algorithm for solving a maze and not incorporating the flood fill alogorithm. I need to identify the flaw in my recursive method solvable. Please note that this is a competetive programming enviorment so coding from the object oriented side of java would be inconvinient.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • 1
    _"this is a competetive programming enviorment so coding from the object oriented side of java would be inconvinient. "_ -- what does that mean? – Jim Garrison Dec 02 '17 at 06:19
  • _"need to identify the flaw in my recursive method solvable"_ well, have you stepped through the code in your IDE debugger? What did you find? – Jim Garrison Dec 02 '17 at 06:20
  • Please visit the [help] and read [ask] to learn how to use this site. Please [edit] your post and include the COMPLETE stack trace, including all CausedBy sections, formatted as code (indent 4 spaces or `{}` button), not blockquote. – Jim Garrison Dec 02 '17 at 06:22
  • As your `solvable()` method walks the maze using recursive calls, it leaves a trail of `x` values behind, but you don't prevent walking back over an `x`, so `solvable()` will just step forward, step back, step forward, step back, step forward, step back, step forward, step back, step forward, step back, step forward, step back, STACK ... OVERFLOW. Perhaps if you change `if(maze[row][col] == 0)` to `if(maze[row][col] != '1')`, both walls (`0`) and trail (`'x'`) will stop the recursion. Now, if you **debugged** your code, you'd know this. --- http://idownvotedbecau.se/nodebugging/ – Andreas Dec 02 '17 at 06:23
  • Also note that no value in `maze` will ever be `0`, since you full it with `'0'` and `'1'` *characters*, not `0` and `1` numbers. Again, if you **debugged** your code, you'd know this. --- [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/5221149) – Andreas Dec 02 '17 at 06:26
  • Be aware that first maze is not solvable, because the exit is inside an impenetrable wall, and therefore cannot be reached. Your code doesn't agree with that. – Andreas Dec 02 '17 at 06:31
  • Downvoted for lack of [mcve] and being unresponsive. You want us to spend our time to help you - so you please spend the time to follow up on the feedback you get. – GhostCat Dec 02 '17 at 07:25

1 Answers1

0

The problem is the infinite recursion in solvable. Why is that? Why it never terminates? Let's take a closer look at how it works:

  • return false if the position is invalid
  • return true if the position is the target
  • return false if the position is the start
    • This is a bit strange thing to do, but whatever, let's move on
  • At this point we know the current position is valid
  • Save the old value of the current position, and mark it with 'x'
  • Try to move in all possible directions
  • Restore the original value of the current position

Where's the flaw in this logic?

When is the marking 'x' used? -> Ha!

If the marking 'x' is not used, what's going to happen? -> Ha!

Imagine this is the maze, and the algorithm always checks the path going down first before checking other directions:

#####
#S E#
# ###
# ###
#####

The algorithm will first go from S until the bottom. At the bottom there is a way to go up, so it goes one step up. There, there is a way to go down, so it goes back down. And it gets stuck going up and down forever.

So the solution is to use the 'x' markings to avoid exploring the same positions forever.

janos
  • 120,954
  • 29
  • 226
  • 236