它们基本上非常相似,只有很小的不同,我遵循了我在网上找到的伪代码(我理解算法本身,我在纸上try 过它,它很管用,我的代码也是如此,但我只是对生成的迷宫有多相似不满意). 伪码:
- 第一步:初始化第一行.
- 步骤2:对于该行中每一列,如果它没有单元格, 创建一个并将其添加到自己的集合中.行中的每个单元格都应该是 在这一点上是一套的一部分.
- 步骤3:从左到右,如果当前单元格和下一个单元格 小区在不同的集合中,随机决定连接到下一个 手机.如果它们连接在一起,则将这些单元的集合合并在一起.
- 第四步:初始化下一行.对于当前行中的每个集合, 每组至少一个单元格向下连接,将该单元格添加到 它与之相连的集合.
- 步骤5:移至下一行,重复步骤2至4.
- 步骤6:当在最后一行时,重复步骤3,但删除 随机性,总是连接到下一个细胞,如果它在一个 不同的布景.不要做任何向下的联系.
我的代码(Java):
import java.util.*;
public class MazeGeneratorEller {
private int[][] grid; // The grid representing the maze
private int[] tiles; // The tiles used to represent walls and paths
private int r; // The number of rows in the maze
private int c; // The number of columns in the maze
private int[] disjointedSet; // The disjoint set data structure used to keep track of connected components
public MazeGeneratorEller(int m, int n, int[] tile) {
this.r = m;
this.c = n;
this.grid = new int[m * 2 + 1][n * 2 + 1];
this.tiles = tile.clone();
this.disjointedSet = new int[m * n];
Arrays.fill(this.disjointedSet, -1);
}
class Vertex {
int x;
int y;
Vertex(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "(" + this.x + "," + this.y + ")";
}
@Override
public boolean equals(Object obj) {
if (obj == null || this.getClass() != obj.getClass())
return false;
if (this == obj)
return true;
Vertex test = (Vertex) obj;
return this.x == test.x && this.y == test.y;
}
@Override
public int hashCode() {
return Objects.hash(this.x, this.y);
}
}
class Edge {
Vertex from;
Vertex to;
Edge(Vertex x, Vertex y) {
this.from = x;
this.to = y;
}
public String toString() {
return this.from + "<->" + this.to;
}
}
HashMap<Vertex, Integer> map = new HashMap<Vertex, Integer>();
ArrayList<Edge> solution = new ArrayList<Edge>();
// Adds all the vertices to the map
private void addVertices() {
int index = 0;
for (int i = 0; i < this.r; i++) {
for (int j = 0; j < this.c; j++)
this.map.put(new Vertex(i, j), index++);
}
}
// Finds the root of the disjoint set that f belongs to
private int find(int f) {
if (this.disjointedSet[f] < 0) {
return f;
} else {
this.disjointedSet[f] = find(this.disjointedSet[f]);
return this.disjointedSet[f]; }
}
// Merges the disjoint sets that the two vertices of the edge belong to
private void union(Edge e) {
int x = find(this.map.get(e.from));
int y = find(this.map.get(e.to));
if (x != y) {
this.solution.add(e);
if (this.disjointedSet[x] <= this.disjointedSet[y]) {
this.disjointedSet[x] += this.disjointedSet[y];
this.disjointedSet[y] = x;
} else {
this.disjointedSet[y] += this.disjointedSet[x];
this.disjointedSet[x] = y;
}
}
}
// Generates the maze
public int[][] generateMaze() {
addVertices();
for (int i = 0; i < this.r - 1; i++) {
for (int j = 0; j < this.c - 1; j++) {
Random rand = new Random(System.nanoTime());
Vertex k = new Vertex(i, j);
if (find(this.map.get(k)) == find(this.map.get(new Vertex(i, j + 1))))
continue;
int choose = rand.nextInt(4);
if (choose == 1)
union(new Edge(k, new Vertex(i, j + 1)));
}
//start of new part
int checkerBelow = 0;
for (int j = 0; j < this.c; j++) {
if (checkerBelow == 0) {
union(new Edge(new Vertex(i, j), new Vertex(i + 1, j)));
checkerBelow = 1;
} else {
int choose = rand.nextInt(2);
if (choose == 1) {
union(new Edge(new Vertex(i, j), new Vertex(i + 1, j)));
}
}
if (j == this.c - 1)
continue;
if (find(this.map.get(new Vertex(i, j))) != find(this.map.get(new Vertex(i, j + 1)))) {
checkerBelow = 0;
}
}
//end of new part
}
for (int j = 0; j < this.c - 1; j++) {
union(new Edge(new Vertex(this.r - 1, j), new Vertex(this.r - 1, j + 1)));
}//The algorithm ends here. The rest is just filling the grid.
// Fill the grid array with walls and paths
for (int i = 0; i < this.grid.length; i++)
Arrays.fill(this.grid[i], this.tiles[1]);
for (Edge e : this.solution) {
int x1 = e.from.x * 2 + 1;
int y1 = e.from.y * 2 + 1;
int x2 = e.to.x * 2 + 1;
int y2 = e.to.y * 2 + 1;
this.grid[x1][y1] = this.tiles[0];
this.grid[x2][y2] = this.tiles[0];
this.grid[(x1 + x2) / 2][(y1 + y2) / 2] = this.tiles[0];
}
return this.grid;
}
}
我将新的部分添加到代码中,它现在工作得很好.