简体   繁体   English

Java中的迷宫路径查找器

[英]Maze path finder in Java

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.在下面的代码中,MazeCoord 是一个程序员创建的类型,它存储了一个坐标类型的位置。 The format is MazeCoord(int x, int y).格式为 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.我的程序现在编译时,到达方法的某些部分并忽略其他部分,因此在所有情况下都说“未找到路径”,并且只将开始位置存储在 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. search() 方法中有一个注释掉的部分,这是我尝试的另一种方法,但我很确定这是错误的,而不是这样做的方法。

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 */ @return 迷宫路径 */

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.客户端可以访问通过 getPath 方法找到的路径。 @return whether path was found. @return 是否找到路径。 */ */

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 */ /** search() 方法的帮助函数,它将执行实际递归以获取通过迷宫的路径 @param row 当前位置的行 @param col 当前位置的列 @return true 如果路径可用 */

    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.其中emptyAndNotChecked()只是检查给定位置是否不是墙并且尚未检查。 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.当您移动到的单元格/图块是目的地或调用addCells()时您不会添加任何新的单元格/图块,您将停止。

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!希望这有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM