UNPKG

rot-js

Version:

A roguelike toolkit in JavaScript

107 lines (106 loc) 3.26 kB
import Map from "./map.js"; import RNG from "../rng.js"; /** * Icey's Maze generator * See http://roguebasin.com/index.php/Simple_maze for explanation */ export default class IceyMaze extends Map { constructor(width, height, regularity = 0) { super(width, height); this._regularity = regularity; this._map = []; } create(callback) { let width = this._width; let height = this._height; let map = this._fillMap(1); width -= (width % 2 ? 1 : 2); height -= (height % 2 ? 1 : 2); let cx = 0; let cy = 0; let nx = 0; let ny = 0; let done = 0; let blocked = false; let dirs = [ [0, 0], [0, 0], [0, 0], [0, 0] ]; do { cx = 1 + 2 * Math.floor(RNG.getUniform() * (width - 1) / 2); cy = 1 + 2 * Math.floor(RNG.getUniform() * (height - 1) / 2); if (!done) { map[cx][cy] = 0; } if (!map[cx][cy]) { this._randomize(dirs); do { if (Math.floor(RNG.getUniform() * (this._regularity + 1)) == 0) { this._randomize(dirs); } blocked = true; for (let i = 0; i < 4; i++) { nx = cx + dirs[i][0] * 2; ny = cy + dirs[i][1] * 2; if (this._isFree(map, nx, ny, width, height)) { map[nx][ny] = 0; map[cx + dirs[i][0]][cy + dirs[i][1]] = 0; cx = nx; cy = ny; blocked = false; done++; break; } } } while (!blocked); } } while (done + 1 < width * height / 4); for (let i = 0; i < this._width; i++) { for (let j = 0; j < this._height; j++) { callback(i, j, map[i][j]); } } this._map = []; return this; } _randomize(dirs) { for (let i = 0; i < 4; i++) { dirs[i][0] = 0; dirs[i][1] = 0; } switch (Math.floor(RNG.getUniform() * 4)) { case 0: dirs[0][0] = -1; dirs[1][0] = 1; dirs[2][1] = -1; dirs[3][1] = 1; break; case 1: dirs[3][0] = -1; dirs[2][0] = 1; dirs[1][1] = -1; dirs[0][1] = 1; break; case 2: dirs[2][0] = -1; dirs[3][0] = 1; dirs[0][1] = -1; dirs[1][1] = 1; break; case 3: dirs[1][0] = -1; dirs[0][0] = 1; dirs[3][1] = -1; dirs[2][1] = 1; break; } } _isFree(map, x, y, width, height) { if (x < 1 || y < 1 || x >= width || y >= height) { return false; } return map[x][y]; } }