0

I am trying to use a Stack(Depth First Search) to solve a maze. I am having a few issues apart from the main issue which is I am currently getting an infinite loop once my stack becomes empty. I have a good understanding of what I need to do I am just having trouble applying it to my code.

I am following this Algorithm to solve the maze:

1.Create an empty stack

2.Search the array for the starting location.

3.Place the starting point onto the stack

4.Remove a point from the stack

5.Test to see if this point is the finish (If it is, end the loop)

6.Otherwise, mark the spot in the maze as evaluated to show path

7.Check spots in the maze that are neighboring the current location (up, down, left, right).

8.If they are not a wall, and haven’t already been evaluated, then add those points to the stack to be other locations to evaluate.

Solve Method with Helper Methods (most errors are in solveDFS())

    //Tries going up,down,left,or right from current location and
    //marks path if valid. The algorithm should finish when reaching
    //the finish spot
    public static boolean solveDFS( char [][] maze ){
    LinkedStack stack = new LinkedStack();
    Point startLoc = findPoint(maze,'s');
    Point finishLoc = findPoint(maze, 'f');
    stack.push(startLoc);

    Point[] neighborSpots = getNeighborSpots(startLoc);

    boolean test = true;
    while ( test ){
        stack.pop();
        if(stack.peek().equals(finishLoc)){
            printMaze(maze);
            test = false;
            return true;
        }else{
            for( Point evaluate : neighborSpots ){
                if( validSpot( stack, maze ) ){
                    placeMarker( stack, maze );
                    if( stack.peek().equals(evaluate)){
                        return true;
                    }
                    removeMarker( stack, maze);
                }
            }
        }
    }
    return false;
}
//Returns true of coordinates of free spot is valid or finish spot
//Should not be off edge of maze
private static boolean validSpot( LinkedStack spot, char [][] maze ){
    if ( spot.peek().x < 0 || spot.peek().x >= maze.length ||
            spot.peek().y < 0 || spot.peek().y >= maze[spot.peek().x].length ) {
        return false;
    }
    return ( maze[spot.peek().x][spot.peek().y] == ' ' || maze[spot.peek().x][spot.peek().y] == 'f' );
}
//Searches the array for a point
private static Point findPoint( char [][] maze, char c ) {
    for ( int i = 0; i < maze.length; i++ ) {
        for ( int j = 0; j < maze[i].length; j++ ) {
            if ( maze[i][j] == c ) {
                return new Point(i, j);
            }
        }
    }
    return null;
}
//returns an array containing coordinates of neighbor spots
private static Point[] getNeighborSpots( Point spot ) {
    Point[] neighborSpots = new Point[4];

    neighborSpots[0] = new Point(spot.x + 1, spot.y);
    neighborSpots[1] = new Point(spot.x, spot.y + 1);
    neighborSpots[2] = new Point(spot.x - 1, spot.y);
    neighborSpots[3] = new Point(spot.x, spot.y - 1);

    return neighborSpots;
}
//Marks the path by adding a '.'
private static void placeMarker( LinkedStack spot, char [][] maze ){
    maze[spot.peek().x][spot.peek().y] = '.';
}
//Removes marker from path by adding a blank space
private static void removeMarker ( LinkedStack spot, char [][] maze ) {
    maze[spot.peek().x][spot.peek().x] = ' ';
}
Raedwald
  • 46,613
  • 43
  • 151
  • 237
JCCS
  • 591
  • 8
  • 22
  • Why not use the program stack instead of using your own? – Bhoot Apr 24 '15 at 06:13
  • @Bhoot Sorry, maybe i should have clarified that this is for an assignment which I am required to use my own. – JCCS Apr 24 '15 at 06:14
  • It seems missing part, i don't see any push except for the start location – Vyncent Apr 24 '15 at 06:15
  • @Vyncent Any idea where else I should be pushing? – JCCS Apr 24 '15 at 06:16
  • Well i would say, if neightbors are valid you need to push them to the stack in order to test their neightbors in next loop – Vyncent Apr 24 '15 at 06:18
  • Can u share us the inputs??? Are u looking to print final path from source to destination??? – Anand Apr 24 '15 at 06:21
  • @Anand Yes, I am looking to print the final maze with the marked path. I can post a sample maze if that is what you are asking for? – JCCS Apr 24 '15 at 06:23
  • Your implementation is messed up. I think you should consider starting from scratch. Too many logical errors. If you are seeking help, post a link to your entire code and I can help. – Bhoot Apr 24 '15 at 06:25
  • @Bhoot http://pastebin.com/p4h8z7Jw That is my main class, I have LinkedStack and Node class but I am sure nothing is wrong with those. – JCCS Apr 24 '15 at 06:30

4 Answers4

1

Your loop changes the loop variable (test) to false if you find a path (yet the effect is irrelevant, because you return directly from the method.

Your loop does never change the loop variable in other cases. Set testto false if all paths are done, and none is successful.

Or simply do not test a boolean variable but emptyness of the stack in your loop expression (while (!stack.isEmpty())).

CoronA
  • 7,717
  • 2
  • 26
  • 53
  • Thank you, this solved the infinite loop issue. Now I am guessing the rest is logical errors because my stack seems to always be empty. – JCCS Apr 24 '15 at 06:32
0

You can not pop from or peek at the top of an empty stack. An implementation of a stack therefore needs to have a predicate (a boolean isEmpty() method) for checking whether the stack is empty. Code that peeks at or pops from the stack must use this predicate and handle the case of an empty stack as a special case, or must be written in a manner that guarantees it never manipulates an empty stack. The latter is harder and rarer in practice.

But what should the pop or peep method of a stack do if it is called for an empty stack? That is, if the method has been called in error? The method should signal the error by throwing a suitable unchecked exception. This will make it much easier to debug the error. Whether the stack is empty is part of the state information if the stack. So the stack is in a state that is invalid for the pop or peek method. So an IllegalStateException would be most suitable.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
  • I have noticed this and it seems it is what is causing my infinite loop. Any idea, on what I should be doing? – JCCS Apr 24 '15 at 06:25
0

3.Place the starting point onto the stack

4.Remove a point from the stack

Are you sure its a good idea ?

Raúl
  • 1,542
  • 4
  • 24
  • 37
0

I have tried to correct the logical errors in your code. The following code should work but it will not place your markers as desired:

public static boolean solveDFS( char [][] maze ){
    LinkedStack stack = new LinkedStack();
    Point startLoc = findPoint(maze,'s');
    Point finishLoc = findPoint(maze, 'f');
    stack.push(startLoc);
    while (!stack.isEmpty()) {
         Point curr = stack.pop();
         if(curr.equals(finishLoc)) {
             printMaze(maze);
             return true;
         } else {
            Point[] neighborSpots = getNeighborSpots(curr);
            for(Point evaluate: neighborSpots) {
                if(validSpot(stack, maze)) {
                    placeMarker(stack, maze);
                    stack.push(evaluate);
                    removeMarker(stack, maze);
                }
            }
        }
    }
    return false;
}
Bhoot
  • 2,614
  • 1
  • 19
  • 36
  • I see the changes and am trying to understand them and they seem logical, but I am getting the same issue that It never seems to meet the if condition. My stack seems to be empty as that is the message I am getting from my LinkedStack class and the maze is not being printed out. – JCCS Apr 24 '15 at 06:48
  • Can you paste the entire code (including LinkedStack and Point class) on ideone and paste the link here? – Bhoot Apr 24 '15 at 08:39
  • This is the main: https://ideone.com/g9BmZE This is LinkedStack: https://ideone.com/riu7kA This is Node: https://ideone.com/WSvdZo I decided to start from scratch and use some algorithms I found on here so it is different than what it was, but am still having trouble. Currently getting IndexOutOfBoundsException. Also I do not have a Points class I am using the Java library one. – JCCS Apr 24 '15 at 09:50