Java 迷宫生成prim算法并非所有单元都被遍历

Java 迷宫生成prim算法并非所有单元都被遍历,java,algorithm,prims-algorithm,Java,Algorithm,Prims Algorithm,我正在尝试实现Prim迷宫生成算法: 从满是墙的网格开始 选择一个单元格,将其标记为迷宫的一部分。添加单元格的墙 到墙列表 当列表中有墙时: 从列表中随机选择一面墙。如果电池在另一侧 还没有进入迷宫: 使墙壁成为通道,并将对面的单元格标记为 迷宫的一部分 将单元的相邻墙添加到墙列表中 如果对面的单元已经在迷宫中,则移除 从列表中删除墙 删除一些实现详细信息我的实现如下所示: Cell[][] maze 是含有细胞的基质。每个单元格都有左/右/上/按钮墙。边界墙标记为布尔边界,并不

我正在尝试实现Prim迷宫生成算法:

  • 从满是墙的网格开始
  • 选择一个单元格,将其标记为迷宫的一部分。添加单元格的墙 到墙列表
  • 当列表中有墙时:
    • 从列表中随机选择一面墙。如果电池在另一侧
      还没有进入迷宫:
      • 使墙壁成为通道,并将对面的单元格标记为 迷宫的一部分
      • 将单元的相邻墙添加到墙列表中
    • 如果对面的单元已经在迷宫中,则移除 从列表中删除墙
删除一些实现详细信息我的实现如下所示:

Cell[][] maze 
是含有细胞的基质。每个单元格都有左/右/上/按钮墙。边界墙标记为
布尔边界
,并不是实现的一部分,因为我希望保持迷宫的框架

public Cell[][] prim(){
    List<Wall> walls = new ArrayList<Wall>();

    //Pick a cell, mark it as part of the maze
    int initialCellI = rnd(sizeX)-1;
    int initialCellJ = rnd(sizeY)-1;
    Cell randomCell = maze[initialCellI][initialCellJ];
    randomCell.setPartOftheMaze(true);

    //Add the walls of the cell to the wall list.
    if ((randomCell.getLeft() != null) && (!randomCell.getLeft().isFrontier()))
        walls.add(randomCell.getLeft());
    if ((randomCell.getRight() != null) && (!randomCell.getRight().isFrontier()))
        walls.add(randomCell.getRight());
    if ((randomCell.getButtom() != null) && (!randomCell.getButtom().isFrontier()))
        walls.add(randomCell.getButtom());
    if ((randomCell.getUp() != null) && (!randomCell.getUp().isFrontier()))
        walls.add(randomCell.getUp());

    //While there are walls in the list:
    while (!walls.isEmpty()){

        //Pick a random wall from the list.
       Wall randomWall = randomElement(walls);
       //pick the cell opposite to this wall. 
       Cell opositeSideCell = getNeightbourCell(randomWall, maze);
       if (opositeSideCell.isPartOftheMaze()){
           //If the cell on the opposite side already was in the maze, remove the wall from the list.
           walls.remove(randomWall);
       }
       else{
          // Make the wall a passage and mark the cell on the opposite side as part of the maze.
           this.removeWall(randomWall, maze);
           opositeSideCell.setPartOftheMaze(true);

            //Add the walls of the cell to the wall list.
            if ((opositeSideCell.getLeft() != null) && (!opositeSideCell.getLeft().isFrontier()))
                walls.add(opositeSideCell.getLeft());
            if ((opositeSideCell.getRight() != null) && (!opositeSideCell.getRight().isFrontier()))
                walls.add(opositeSideCell.getRight());
            if ((opositeSideCell.getButtom() != null) && (!opositeSideCell.getButtom().isFrontier()))
                walls.add(opositeSideCell.getButtom());
            if ((opositeSideCell.getUp() != null) && (!opositeSideCell.getUp().isFrontier()))
                walls.add(opositeSideCell.getUp());   
       }
    }
    return maze;
}
public Cell[]prim(){
列表墙=新的ArrayList();
//选择一个单元格,将其标记为迷宫的一部分
int initialCellI=rnd(sizeX)-1;
int initialCellJ=rnd(sizeY)-1;
细胞随机细胞=迷宫[initialCellI][initialCellJ];
randomCell.SetPartOfMate(真);
//将单元的墙添加到墙列表中。
如果((randomCell.getLeft()!=null)&&(!randomCell.getLeft().isFrontier())
add(randomCell.getLeft());
如果((randomCell.getRight()!=null)&(!randomCell.getRight().isFrontier())
add(randomCell.getRight());
如果((randomCell.getButtom()!=null)&(!randomCell.getButtom().isFrontier())
add(randomCell.getButtom());
如果((randomCell.getUp()!=null)&(!randomCell.getUp().isFrontier())
添加(randomCell.getUp());
//当列表中有墙时:
而(!walls.isEmpty()){
//从列表中随机选择一面墙。
墙随机墙=随机元素(墙);
//选择此墙对面的单元。
Cell-opositeSideCell=getNeightbourCell(随机墙,迷宫);
if(opositeSideCell.ispartofmaze()){
//如果对面的单元格已经在迷宫中,请从列表中删除该墙。
墙。移除(墙);
}
否则{
//让墙成为通道,并将对面的单元标记为迷宫的一部分。
此。移除墙(随机墙、迷宫);
opositeSideCell.setpartofmaze(true);
//将单元的墙添加到墙列表中。
如果((opositeSideCell.getLeft()!=null)&(!opositeSideCell.getLeft().isFrontier())
add(opositeSideCell.getLeft());
如果((opositeSideCell.getRight()!=null)&(!opositeSideCell.getRight().isFrontier())
add(opositeSideCell.getRight());
如果((opositeSideCell.getButtom()!=null)&(!opositeSideCell.getButtom().isFrontier())
add(opositeSideCell.getButtom());
如果((opositeSideCell.getUp()!=null)&(!opositeSideCell.getUp().isFrontier())
add(opositeSideCell.getUp());
}
}
返回迷宫;
}
我的问题是我的迷宫没有完成,也不是所有的细胞都被穿过。 有时只有少数单元格被遍历,几乎所有单元格都被遍历。我想我错过了什么,但我想不出是什么

请帮忙

部分穿越迷宫见下图


我解决了这个问题。 这纯粹是Java问题,与算法无关。我比较了两堵墙之间的距离

public class Wall{

    Point p1;
    Point p2;
    }

    public class Point{
    int x;
    int y;
    }
如果我使用p1和p2实现Wall类equals()和hashCode()。然后在
LeTyCal.WrrthWALL将等于RealCy.LeWWALWALL,这是问题。

提醒我C++项目:)@ 3Mun-1STVFW,尤其是基于Ajax的客户端:)是否有可能在ISBEXT代码中存在错误,并且迷宫只是部分遍历,因为ISPORT比它应该返回的次数更频繁?@我不这么认为,因为isFrontier只是getter,布尔frontier的默认值为false。嗯,在这种情况下,我会非常仔细地检查您的getLeft、getRight等实现。迷宫中没有向上或向左的路径,因此我怀疑这些函数返回错误的答案,这意味着迷宫只能在初始种子点的正下方生长。也许你可以发布代码?