我正在编写一个迷宫生成器。我有一个“Cell”类,如下所示:
public class Cell {
public boolean northWall;
public boolean southWall;
public boolean eastWall;
public boolean westWall;
public Cell north;
public Cell south;
public Cell east;
public Cell west;
public boolean visited;
public Cell() {
northWall = true;
southWall = true;
eastWall = true;
westWall = true;
visited = false;
}
public boolean hasUnvisitedNeighbors() {
return ((north != null && !north.Visited)
|| (south != null && !south.Visited)
|| (east != null && !east.Visited) || (west != null && !west.Visited));
}
public Cell removeRandomWall() {
List<Cell> unvisitedNeighbors = new ArrayList<Cell>();
if (north != null && !north.Visited)
unvisitedNeighbors.add(north);
if (south != null && !south.Visited)
unvisitedNeighbors.add(south);
if (west != null && !west.Visited)
unvisitedNeighbors.add(west);
if (east != null && !east.Visited)
unvisitedNeighbors.add(east);
if (unvisitedNeighbors.size() == 0) {
return null;
} else {
Random randGen = new Random();
Cell neighbor = unvisitedNeighbors.get(randGen
.nextInt((unvisitedNeighbors.size())));
if (neighbor == north) {
northWall = false;
north.southWall = false;
return north;
} else if (neighbor == south) {
southWall = false;
south.northWall = false;
return south;
} else if (neighbor == west) {
westWall = false;
west.eastWall = false;
return west;
} else if (neighbor == east) {
eastWall = false;
east.westWall = false;
return east;
}
return null;
}
}
}
我的程序中的迷宫只是一个二维的单元格数组。创建数组后,我手动进入并设置所有对相关单元格(北,南,东,西)的引用。
我正在尝试清理的是 removeRandomWall()。假设随机选择其访问标志设置为false的相邻Cell,并删除该单元格和连接它们的相邻单元格中的墙壁。
因此,需要考虑所有未访问过的相邻单元格,随机选择一个,然后在此单元格中设置墙,将相邻的单元格设置为false,这样它们之间就有了一条路径。我已经尝试过了,但它似乎非常笨拙。
任何人都可以帮助我吗?
答案 0 :(得分:4)
而不是有4个独立的成员:
public Cell North;
public Cell South;
public Cell East;
public Cell West;
只有一个数组:
public Cell [] cells = new Cell[4];
和4个常数:
public final int NORTH = 0;
public final int EAST = 1;
public final int SOUTH = 2;
public final int WEST = 3;
它可以让删除随机墙变得更容易。
答案 1 :(得分:3)
对方向进行枚举,然后通过给出方向来访问墙壁和邻居。
您应该将您的成员变量设为私有,并以小写形式编写。
答案 2 :(得分:1)
第一次尝试,如果可以的话,我会将成员变量设为私人决赛:
public class Cell {
public boolean NorthWall;
public boolean SouthWall;
public boolean EastWall;
public boolean WestWall;
public Cell North;
public Cell South;
public Cell East;
public Cell West;
public boolean Visited;
public Cell() {
NorthWall = true;
SouthWall = true;
EastWall = true;
WestWall = true;
Visited = false;
}
public boolean hasUnvisitedNeighbors() {
return unvisited(North) || unvisited(South) || unvisited(East) || unvisited(West);
}
private List<Cell> getUnvisitedNeighbors() {
List<Cell> result = new ArrayList<Cell>();
if (unvisited(North))
result.add(North);
if (unvisited(South))
result.add(South);
if (unvisited(West))
result.add(West);
if (unvisited(East))
result.add(East);
return result;
}
private boolean unvisited(Cell cell) {
return cell != null && !cell.Visited;
}
private Cell getRandomUnvisitedNeighbor() {
Random randGen = new Random();
List<Cell> unvisitedNeighbors = getUnvisitedNeighbors();
return unvisitedNeighbors.get(randGen.nextInt((unvisitedNeighbors.size())));
}
public Cell removeRandomWall() {
if (!hasUnvisitedNeighbors()) {
return null;
}
Cell neighbor = getRandomUnvisitedNeighbor();
if (neighbor == North) {
NorthWall = false;
North.SouthWall = false;
} else if (neighbor == South) {
SouthWall = false;
South.NorthWall = false;
} else if (neighbor == West) {
WestWall = false;
West.EastWall = false;
} else if (neighbor == East) {
EastWall = false;
East.WestWall = false;
}
return neighbor;
}
}
答案 3 :(得分:0)
尝试使用“null Cell”对象删除对null的检查...
public static final Cell NULL_CELL = new Cell();
所以你可以使用null表示不存在这样的单元格,你现在可以使用NULL_CELL。
现在你可以替换
if (north != null && !north.Visited)
unvisitedNeighbors.add(north);
带
if (!north.isVisited()) {
unvisitedNeighbors.add(north);
}
通常在Java中,成员变量是私有的,并且您使用“getters”来访问它们......
private boolean northWall;
private boolean southWall;
private boolean eastWall;
private boolean westWall;
private Cell north;
private Cell south;
private Cell east;
private Cell west;
private boolean visited;
public boolean hasNorthWall() {
return northWall;
}
public Cell getNorthCell() {
return north;
}
// etc.