首页 文章

Java中的迷宫路径查找器

提问于
浏览
0

我正在尝试使用递归来解决迷宫问题 . 在下面的代码中,MazeCoord是一个程序员创建的类型,用于存储坐标类型位置 . 格式为MazeCoord(int x,int y) . 我的程序现在编译,到达方法的某些部分并忽略另一个,因此在所有情况下都说“找不到路径”,只将起始位置存储在LinkedList mazePath中 . 在search()方法中有一个注释掉的部分,这是我尝试的另一种方式,但我很确定它是错误的而不是这样做的方法 .

任何帮助表示赞赏 .

递归代码:

/ **返回迷宫中的路径 . 第一个元素是起始位置,最后一个元素是退出位置 . 如果没有路径,或者在搜索之前调用此路径,则返回空列表 .

@return迷宫路径* /

public LinkedList<MazeCoord> getPath() {
       return mazePath; 
}

/ **如果有迷宫,找到迷宫中的路径 . 客户端可以访问通过getPath方法找到的路径 . @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;
       */
   }

/ ** search()方法的辅助函数将执行实际递归以获取通过迷宫的路径@param行currentLoc @param col的行currentLoc @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;
    }

1 回答

  • 0

    首先,我想建议你this link,它解释了一种最常见的寻路算法 .

    您也可以找到一个简短的教程here在我看来,本教程将很好地满足您的要求,因为它以网格为例 .

    不需要使用递归函数来执行路径寻找算法 . 你可以做的是保持两个列表:一个已经'checked'单元格/瓦片和另一个尚未列出的列表 .

    接下来,您将从您想要开始路径的点开始,并检查从此点可以到达的所有单元格/图块,例如:

    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))
    }
    

    emptyAndNotChecked() 只是检查给定位置是否不是墙并且尚未检查 . 当然你也可以进行对角线检查!

    此时你想要找到你想要添加更多单元格的下一个单元格/平铺,你可以通过检查所有“未经检查”的单元格/平铺并通过应用每个“权重”功能来实现这一点 . 为您提供给定目的地的最佳单元格/区块,基本实现可以是:

    float weight(Point current,Point end) {
       return Math.sqrt(Math.pow(current.x-end.x,2)+Math.pow(current.y-end.y,2));
    }
    

    此功能将允许您找到最合适的单元格/磁贴导航,一旦找到它(重量最轻的那个),您移动到此一个并再次调用第一个函数来添加更多单元格/磁贴 .

    当您移动的单元格/磁贴是目标或调用 addCells() 时,您将停止添加任何新单元格/磁贴 .

    当然,这只是一种基本的方法,并且可以应用很多改进 . 希望这有用!

相关问题