Java深度优先搜索迷宫生成算法陷入困境

时间:2014-03-01 18:07:45

标签: java depth-first-search maze

我有一个使用深度优先搜索的迷宫生成算法 它首先生成一个原始迷宫,如下所示:
raw maze
然后使用此算法创建迷宫:http://www.mazeworks.com/mazegen/mazetut/index.html
结果如下:
result
红色像素标志着目标,绿色像素标志着目标 它被卡在目标上并来回跳跃,直到它认为完成为止 迷宫发生器来源:

public Maze generate(int width, int height) {
    Maze maze = getRawMaze(width, height);

    List<Point> cellStack = new LinkedList<Point>();
    int totalAirCells = maze.getTotalAirCells();
    Point currentCell = maze.getRandomAirCell(ran);
    maze.setCellTypeAt(currentCell, Maze.CellType.START);       
    int visitedCells = 1;

    while(visitedCells<totalAirCells) {
        Point[] unvisitedNeighbors = getUnvisitedNeighbors(maze, currentCell);
        if(unvisitedNeighbors.length!=0) {
            System.out.println("Go Foward");
            Point newCell = unvisitedNeighbors[ran.nextInt(unvisitedNeighbors.length)];
            maze.connect(newCell, currentCell);
            cellStack.add(currentCell);
            currentCell = newCell;
            visitedCells++;
        }else {
            System.out.println("Go Back");
            Point recentCell = cellStack.get(cellStack.size()-1);
            cellStack.remove(cellStack.size()-1);
            currentCell = recentCell;
        }
    }

    maze.setCellTypeAt(currentCell, Maze.CellType.GOAL);

    return maze;
}

public Point[] getUnvisitedNeighbors(Maze maze, Point p) {
    List<Point> unvisitedNeighbors = new ArrayList<Point>();
    Point[] neighbors = maze.getNeighbors(p);
    for(Point n : neighbors) {
        if(maze.getSurroundingWalls(n)==4)unvisitedNeighbors.add(n);
    }
    return unvisitedNeighbors.toArray(new Point[unvisitedNeighbors.size()]);
}

其他来源:

public int getSurroundingWalls(Point p) {
    if(getCellTypeAt(p)==CellType.AIR) {
        int walls = 0;
        if(getCellTypeAt(new Point(p.x+1, p.y))==CellType.WALL)walls++;
        if(getCellTypeAt(new Point(p.x-1, p.y))==CellType.WALL)walls++;
        if(getCellTypeAt(new Point(p.x, p.y+1))==CellType.WALL)walls++;
        if(getCellTypeAt(new Point(p.x+1, p.y-1))==CellType.WALL)walls++;
        return walls;
    }else return -1;
}

public Point[] getNeighbors(Point p) {
    Point[] neighbors = new Point[4];
    neighbors[0] = new Point(p.x+2, p.y);
    neighbors[1] = new Point(p.x-2, p.y);
    neighbors[2] = new Point(p.x, p.y+2);
    neighbors[3] = new Point(p.x, p.y-2);
    return neighbors;
}

public void connect(Point a, Point b) {
    if((a.x==b.x-2)&&(a.y==b.y))setCellTypeAt(new Point(a.x+1, a.y), CellType.AIR);
    else if((a.x==b.x+2)&&(a.y==b.y))setCellTypeAt(new Point(a.x-1, a.y), CellType.AIR);
    else if((a.x==b.x)&&(a.y==b.y-2))setCellTypeAt(new Point(a.x, a.y+1), CellType.AIR);
    else if((a.x==b.x)&&(a.y==b.y+2))setCellTypeAt(new Point(a.x, a.y-1), CellType.AIR);
}

public Point getRandomAirCell(Random ran) {
    List<Point> airCells = new LinkedList<Point>();
    for(int x = 0; x<getWidth(); x++) {
        for(int y = 0; y<getHeight(); y++){
            Point p = new Point(x, y);
            if(getCellTypeAt(p)==Maze.CellType.AIR)airCells.add(p);
        }
    }
    return airCells.get(ran.nextInt(airCells.size()));
}

public int getTotalAirCells() {
    int airCells = 0;
    for(int x = 0; x<getWidth(); x++) {
        for(int y = 0; y<getHeight(); y++){
            if(getCellTypeAt(new Point(x, y))==Maze.CellType.AIR)airCells++;
        }
    }
    return airCells;
}

为什么算法没有完成迷宫?

1 个答案:

答案 0 :(得分:1)

检查getSurroundingWalls(),检查的第四个点是p.x+1, p.y-1,但我认为它应该是p.x, p.y-1