I'm trying to solve the Maze using recursion. In the following piece of code, MazeCoord is a programmer created type that stores a coordinate type location. The format is MazeCoord(int x, int y). My program when compiled right now, reaches some parts of the method and ignores the other and hence says "No Path Found" in all cases and only stores the start location in the LinkedList mazePath. There's a commented out part in the search() method that was another way I was trying out but I'm pretty sure that it is wrong and not the way to do it.
Any help is appreciated.
Recursion code:
/** Returns the path through the maze. First element is starting location, and last element is exit location. If there was not path, or if this is called before search, returns empty list.
@return the maze path */
public LinkedList<MazeCoord> getPath() {
return mazePath;
}
/** Find a path through the maze if there is one. Client can access the path found via getPath method. @return whether path was found. */
public boolean search() {
currentLoc = new MazeCoord(startLoc.getRow(), startLoc.getCol());
visitedPath = new boolean[mazeData.length][mazeData[0].length];
mazePath=new LinkedList<MazeCoord>();
if(hasWallAt(startLoc) || hasWallAt(endLoc)){
return false;
}
else{
mazePath.add(currentLoc);
return appendToSearch(currentLoc.getRow(), currentLoc.getCol());
}
/**
System.out.println("try1");
mazePath.add(new MazeCoord(startLoc.getRow(), startLoc.getCol()));
boolean searchResult = appendToSearch(numRows()-1, numCols()-1);
System.out.println("test: " + searchResult);
System.out.println("test2: row, col --> " + (numRows()-1) + " , " + (numCols()-1));
System.out.println("test3: wallValue:" + hasWallAt(new MazeCoord(numRows()-1,numCols()-1)));
if(searchResult){
System.out.println("try2");
mazePath.add(new MazeCoord(numRows()-1, numCols()-1));
}
return searchResult;
*/
}
/**Helper function for the search() method that will perform the actual recursion to obtain the path through the maze @param row the row for the currentLoc @param col the column for the currentLoc @return true iff a path is available */
private boolean appendToSearch(int row, int col) {
//Check if within the maze
if((row - 1 < 0) || (col - 1 < 0) || (row + 1 > numRows()) || (col + 1 > numCols())){
return false;
}
//Check if the position is the exit location
if(row == endLoc.getRow() && col == endLoc.getCol()){
mazePath.add(new MazeCoord(row, col));
return false;
}
//Check for Wall
if(hasWallAt(new MazeCoord(row, col))){
return false;
}
//Check if the position has already been visited
if(visitedPath[row][col]){
return false;
}
//If all pass --> add to visitedPath
visitedPath[row][col]=true;
//Check to the Right
if(appendToSearch(row, col + 1)){
mazePath.add(new MazeCoord(row, col + 1));
return true;
}
//Check Downwards
else if(appendToSearch(row + 1, col)){
mazePath.add(new MazeCoord(row + 1, col));
return true;
}
//Check to the Left
else if(appendToSearch(row, col - 1)){
mazePath.add(new MazeCoord(row, col - 1));
return true;
}
//Check Upwards
else if(appendToSearch(row - 1, col)){
mazePath.add(new MazeCoord(row - 1, col));
return true;
}
return false;
}
first of all I would like to suggest you this link which explains one of the most common pathfinding algorithms out there.
A short tutorial you could also follow can be found here In my opinion this tutorial will fit well with your requirements, since it takes a grid as an example.
It's not required to use a recursive function to perform a pathfinding algorithm. What you could do could be to hold two lists: one of already 'checked' cells/tiles and another one of those which have not yet.
Successively you will start from the point where you want to begin the path and will check for all the cells/tiles which can be reached from this point, like:
void addCells(Point current) {
// Left
if (emptyAndNotChecked(current.x-1,current.y)) // Checking for walls here
cellsToCheck.add(new Point(x-1,y)) // Adding this cell to the list
// Right
if (emptyAndNotChecked(current.x+1,current.y))
cellsToCheck.add(new Point(x+1,y))
// Top
if (emptyAndNotChecked(current.x,current.y+1))
cellsToCheck.add(new Point(x,y+1))
// Bottom
if (emptyAndNotChecked(current.x,current.y-1))
cellsToCheck.add(new Point(x,y-1))
}
Where emptyAndNotChecked()
just checks whether the given position is not a wall and has not already been checked.
Of course you can also perform a diagonal check!
At this point you want to find the next cell/tile from where you wanna add more cells, you can do this by checking all the "unchecked" cells/tiles and by applying to each one of the a of "weight" function which will give you the best cell/tile for a given destination, a basic implementation could be this:
float weight(Point current,Point end) {
return Math.sqrt(Math.pow(current.x-end.x,2)+Math.pow(current.y-end.y,2));
}
This function will allow you to find the most suitable cell/tile to navigate to, once found it (the one with the lowest weight), you move to this one and call again the first function to add more cells/tiles.
You will stop when the cell/tile you moved to is the destination or when calling the addCells()
you don't add any new cell/tile.
Of course this is just a basic way to do that and there are a lot of improvements that can be applied. Hope this is helpful!