views:

623

answers:

2

I am trying to write a program that is given a maze and tries to find the way out. M is the entrance, E is the exit, 1s are walls, and 0s are pathways. It is supposed to find each path and put P in the path. It is supposed to find all available paths. Right now it finds part of a path.

Here is the code:

public class Maze 
{
    private int size;
    private String[][] board;
    private int total; //# of boards
    private int eX;
    private int eY;
    private int mX;
    private int mY;

    public Maze( int size, String[][] board )
    {
     this.size = size;
     this.board = board;
     total = 0;

    }

    private void find( String c )
    {
     int x=0, y=0;
     for( int i = 0; i < size; i++ )
     {
      for( int j = 0; j < size; j++ )
      {
       if( board[i][j].equals(c) )
       {
        x = i;
        y = j;
       }
      }
     }
     if( c.equals("M") )
     {
      mX = x;
      mY = y;
     }
     else if( c.equals("E") )
     {
      eX = x;
      eY = y;
     }
    }

    public void findPath(  )
    {
     find( "M" );
     find( "E" );
     findNext( mX, mY );
    }

    public void findNext( int x, int y )
    { 
     String last = board[x][y];
            if( board[x][y].equals("P") ) board[x][y] = "1";
     board[x][y] = "P";

     if( rightAvailability(x,y) )
     {
      findNext(x+1, y);
     }
     else if( leftAvailability(x,y) )
     {
      findNext(x-1, y);
     }
     else if( aboveAvailability(x,y) )
     {
      findNext(x, y+1);
     }
     else if( belowAvailability(x,y) )
     {
      findNext(x, y-1);
     }
     else
     {
      total++;
      printBoard();
     }

     board[x][y]= last;
    }

    public boolean rightAvailability( int x, int y )
    {
     if( x+1 >= size ) return false;
     else if( board[x+1][y].equals("1") ) return false;
     else if( board[x+1][y].equals("P") ) return false;
     else return true;
    }
    public boolean leftAvailability( int x, int y )
    {
     if( x-1 < 0) return false;
     else if( board[x-1][y].equals("1") ) return false;
     else if( board[x-1][y].equals("P") ) return false;
     else return true;
    }
    public boolean aboveAvailability( int x, int y )
    {
     if( y+1 >= size ) return false;
     else if( board[x][y+1].equals("1") ) return false;
     else if( board[x][y+1].equals("P") ) return false;
     else return true;
    }
    public boolean belowAvailability( int x, int y )
    {
     if( y-1 < 0) return false;
     else if( board[x][y-1].equals("1") ) return false;
     else if( board[x][y-1].equals("P") ) return false;
     else return true;
    }

    public void printBoard()
    {
     System.out.println( "The board number " +total+ " is: ");
     for(int i=0; i< size; i++ )
     {
      for(int j=0; j< size; j++ )
      {
       if( (i==mX) && (j==mY) )
       {
        System.out.print("M");
       }
       else if( (i==eX) && (j==eY) )
       {
        System.out.print("E");
       }
       else if( board[i][j].equals("1") )
       {
        System.out.print("1");
       }
       else if( board[i][j].equals("0") )
       {
        System.out.print("0");
       }
       else
       {
        System.out.print("P");
       }
      }
      System.out.println();
     }
    }
}

Here is the tester:

public class MazeTester 
{
    public static void main(String[] args) 
    {
     int size = 11;
     String[][] board = new String[][]
      {
       {"1","1","1","1","1","1","1","1","1","1","1"},
       {"1","0","0","0","0","0","1","0","0","0","1"},
       {"1","0","1","0","0","0","1","0","1","0","1"},
       {"E","0","1","0","0","0","0","0","1","0","1"},
       {"1","0","1","1","1","1","1","0","1","0","1"},
       {"1","0","1","0","1","0","0","0","1","0","1"},  
       {"1","0","0","0","1","0","1","0","0","0","1"},
       {"1","1","1","1","1","0","1","0","0","0","1"},
       {"1","0","1","M","1","0","1","0","0","0","1"},
       {"1","0","0","0","0","0","1","0","0","0","1"},
       {"1","1","1","1","1","1","1","1","1","1","1"}, 
      };


     Maze m = new Maze( size, board );
     m.findPath();
    }
}

Here is the current output:

The board number 1 is: 
11111111111
1PPPPP1PPP1
1P1PPP1P1P1
EP1PPPPP1P1
101111101P1
10101PPP1P1
10001P1PPP1
11111P1PP01
101M1P1PP01
100PPP1PP01
11111111111
The board number 2 is: 
11111111111
1PPPPP1PPP1
1P1PPP1P1P1
EP100PPP1P1
101111101P1
10101PPP1P1
10001P1PPP1
11111P1PP01
101M1P1PP01
100PPP1PP01
11111111111
The board number 348 is: 
11111111111
1PPPPP10001
1P1PPP10101
EP1PPPPP101
1011111P101
10101PPP101
10001P10001
11111P10001
101M1P10001
100PPP10001
11111111111

EDIT: I added if( board[x][y].equals("P") ) board[x][y] = "1"; at the beginning of findIndex. I also fixed the x <= 0 problem. I updated the output to what I am getting now (it is actually print 348 similar boards).

+1  A: 

I put a partial Guess at the line:

else if( belowAvailability(x,y) )
{
        findNext(x, x-1);
}

x-1 should be y-1

Another problem you'll find is in the fact that you're using else if blocks. If you encounter a branch, say

1E1
101
1P0
1P1

You will try to go right first, and then when that fails miserably, it won't try to go up. You can actually see that in the test output,

_._._789_._
_..._6_A54_
_____5_B23_
_._M_4_C10_
_..123_DEF_
___________

Numbered in Hex for easy reading convenience. It gets into the lower right corner, then gets stuck; having nowhere else to go the board is printed, and the recursion ends with no backtracking into untested squares.

EDIT again. Still looking, but in the left/right availability you have another x/y mismatch, and you probably only want to deny availability when x-1 < 0 (or y-1); as the goal node is at y=0.

With those changes, and having print trigger only when x==eX && y==eY, I'm getting output of solutions. A great many solutions, but solutions.

One more humorous fact for edit count: you have left/right and up/down backwards. The x coordinate is specifying the row of the input you're looking at, and the y coordinate is specifying the column. It's reasonably common to use r/c in cases like this.

CoderTao
That didnt fix my problem but thanks for catching that!
Josh Curren
Josh Curren
CoderTao
I am getting 348 solutions now. I did notice the x/y coordinates were backward but it was not until I was debugging it, and I didnt want to mess with fixing that.
Josh Curren
Thanks for all the help!!!!!!
Josh Curren
A: 

Standard path finding algorithms should work, you'll need to modify them to match your world definition.

But A* or D* algorithms work pretty well. They use a graph, which you should be able to define from your world definition. (http://en.wikipedia.org/wiki/A*)

Also Dijstra's algorithm should work at finding a path (again uses a graph). It is commonly used for network routing - but it also works for normal path finding. (http://en.wikipedia.org/wiki/Dijkstra%27s%5Falgorithm)

Basically my approach would be to turn your maze definition into a graph (nodes are "join points", edges are the "hallways") and then use one of those algorithms.

Aidos