maze/eller
埃勒
选一种语言就能看到代码
def eller_maze(w, h, rng): links = [0] * (w * h) set_of = [0] * w next_set = 1 for y in range(h): for x in range(w): if set_of[x] == 0: set_of[x] = next_set next_set += 1 for x in range(w - 1): if set_of[x] == set_of[x + 1]: continue if y + 1 < h and rng.below(2) == 0: continue room = y * w + x carve(links, room, neighbor(room, 1), 1) old = set_of[x + 1] for k in range(w): if set_of[k] == old: set_of[k] = set_of[x] if y + 1 == h: break seen = set() down = [rng.below(2) == 0 for x in range(w)] for x in range(w): if down[x]: seen.add(set_of[x]) for x in range(w): if set_of[x] not in seen: seen.add(set_of[x]) down[x] = True for x in range(w): room = y * w + x if down[x]: carve(links, room, neighbor(room, 2), 2) else: set_of[x] = 0 return links
function ellerMaze(w, h, rng) { const links = new Array(w * h).fill(0); const setOf = new Array(w).fill(0); const down = new Array(w).fill(false); let nextSet = 1; for (let y = 0; y < h; y++) { for (let x = 0; x < w; x++) { if (setOf[x] === 0) setOf[x] = nextSet++; } for (let x = 0; x + 1 < w; x++) { if (setOf[x] === setOf[x + 1]) continue; if (y + 1 < h && rng.below(2) === 0) continue; const room = y * w + x; carve(links, room, neighbor(room, 1), 1); const old = setOf[x + 1]; for (let k = 0; k < w; k++) { if (setOf[k] === old) setOf[k] = setOf[x]; } } if (y + 1 === h) break; const seen = new Set(); for (let x = 0; x < w; x++) { down[x] = rng.below(2) === 0; if (down[x]) seen.add(setOf[x]); } for (let x = 0; x < w; x++) { if (seen.has(setOf[x])) continue; seen.add(setOf[x]); down[x] = true; } for (let x = 0; x < w; x++) { const room = y * w + x; if (down[x]) carve(links, room, neighbor(room, 2), 2); else setOf[x] = 0; } } return links; }
void eller_maze(int links[], int w, int h) { int n = w * h; int* set_of = calloc(w, sizeof(int)); char* down = malloc(w); char* seen = calloc(n + 1, 1); int next_set = 1; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (set_of[x] == 0) set_of[x] = next_set++; } for (int x = 0; x + 1 < w; x++) { if (set_of[x] == set_of[x + 1]) continue; if (y + 1 < h && rand() % 2 == 0) continue; int room = y * w + x; carve(links, room, neighbor(room, 1), 1); int old = set_of[x + 1]; for (int k = 0; k < w; k++) { if (set_of[k] == old) set_of[k] = set_of[x]; } } if (y + 1 == h) break; for (int x = 0; x < w; x++) seen[set_of[x]] = 0; for (int x = 0; x < w; x++) { down[x] = rand() % 2; if (down[x]) seen[set_of[x]] = 1; } for (int x = 0; x < w; x++) { if (seen[set_of[x]]) continue; seen[set_of[x]] = 1; down[x] = 1; } for (int x = 0; x < w; x++) { int room = y * w + x; if (down[x]) carve(links, room, neighbor(room, 2), 2); else set_of[x] = 0; } } free(set_of); free(down); free(seen); }
void eller_maze(std::vector<int>& links, int w, int h, std::mt19937& rng) { std::vector<int> set_of(w, 0); std::vector<int> down(w, 0); std::unordered_set<int> seen; std::uniform_int_distribution<int> coin(0, 1); int next_set = 1; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (set_of[x] == 0) set_of[x] = next_set++; } for (int x = 0; x + 1 < w; x++) { if (set_of[x] == set_of[x + 1]) continue; if (y + 1 < h && coin(rng) == 0) continue; int room = y * w + x; carve(links, room, neighbor(room, 1), 1); int old = set_of[x + 1]; for (int& id : set_of) { if (id == old) id = set_of[x]; } } if (y + 1 == h) break; seen.clear(); for (int x = 0; x < w; x++) { down[x] = coin(rng); if (down[x]) seen.insert(set_of[x]); } for (int x = 0; x < w; x++) { if (seen.insert(set_of[x]).second) down[x] = 1; } for (int x = 0; x < w; x++) { int room = y * w + x; if (down[x]) carve(links, room, neighbor(room, 2), 2); else set_of[x] = 0; } } }
static int[] EllerMaze(int w, int h, Random rng) { int[] links = new int[w * h]; int[] setOf = new int[w]; bool[] down = new bool[w]; var seen = new HashSet<int>(); int nextSet = 1; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (setOf[x] == 0) setOf[x] = nextSet++; } for (int x = 0; x + 1 < w; x++) { if (setOf[x] == setOf[x + 1]) continue; if (y + 1 < h && rng.Next(2) == 0) continue; int room = y * w + x; Carve(links, room, Neighbor(room, 1), 1); int old = setOf[x + 1]; for (int k = 0; k < w; k++) { if (setOf[k] == old) setOf[k] = setOf[x]; } } if (y + 1 == h) break; seen.Clear(); for (int x = 0; x < w; x++) { down[x] = rng.Next(2) == 0; if (down[x]) seen.Add(setOf[x]); } for (int x = 0; x < w; x++) { if (seen.Add(setOf[x])) down[x] = true; } for (int x = 0; x < w; x++) { int room = y * w + x; if (down[x]) Carve(links, room, Neighbor(room, 2), 2); else setOf[x] = 0; } } return links; }
static int[] ellerMaze(int w, int h, Random rng) { int[] links = new int[w * h]; int[] setOf = new int[w]; boolean[] down = new boolean[w]; Set<Integer> seen = new HashSet<>(); int nextSet = 1; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (setOf[x] == 0) setOf[x] = nextSet++; } for (int x = 0; x + 1 < w; x++) { if (setOf[x] == setOf[x + 1]) continue; if (y + 1 < h && rng.nextInt(2) == 0) continue; int room = y * w + x; carve(links, room, neighbor(room, 1), 1); int old = setOf[x + 1]; for (int k = 0; k < w; k++) { if (setOf[k] == old) setOf[k] = setOf[x]; } } if (y + 1 == h) break; seen.clear(); for (int x = 0; x < w; x++) { down[x] = rng.nextInt(2) == 0; if (down[x]) seen.add(setOf[x]); } for (int x = 0; x < w; x++) { if (seen.add(setOf[x])) down[x] = true; } for (int x = 0; x < w; x++) { int room = y * w + x; if (down[x]) carve(links, room, neighbor(room, 2), 2); else setOf[x] = 0; } } return links; }