I guess I need to explain my answer in detail.
Here is the code in javascript:
// C-flavour random
let gsrand = 0
function srand(x) { gsrand = x }
function rand() {
gsrand = (gsrand*1103515245+12345)&0xffffffff
return gsrand>>16 & 32767
}
class Chunk{
matrix
constructor() {
// suppose the map is divided into 64×64 chunks
this.matrix = new Uint8Array(4096)
}
}
Chunk.prototype.put = function(x, y, type) {
this.matrix[x<<6|y] = type == 'space' ? 0 : 1
}
/* * * Core * * */
Chunk.prototype.generate__infmaze_4 = function(lx, ly, rx, ry) { // split the map recursively
let x0 = rx - lx
let y0 = ry - ly
// room small enough (width = 1)
if(x0==0 || y0==0) {
for(let i = lx; i <= rx; i++) {
for(let j = ly; j <= ry; j++) this.put(i, j, 'space')
}
return
}
let mx = lx+2*(rand()%(x0>>1))+1
let my = ly+2*(rand()%(y0>>1))+1
for(let i = lx; i <= rx; i++) this.put(i, my, 'wall')
for(let i = ly; i <= ry; i++) this.put(mx, i, 'wall')
// split the map into four smaller rooms
this.generate__infmaze_4(lx, ly, mx-1, my-1)
this.generate__infmaze_4(lx, my+1, mx-1, ry)
this.generate__infmaze_4(mx+1, ly, rx, my-1)
this.generate__infmaze_4(mx+1, my+1, rx, ry)
// three exits serve as passages through rooms
let d = rand()%4
let myl = (my-ly+1) >> 1
let myr = (ry-my+1) >> 1
let mxl = (mx-lx+1) >> 1
let mxr = (rx-mx+1) >> 1
if(d == 0) {
this.put(rx - 2*(rand()%mxr), my, 'space')
this.put(mx, ly + 2*(rand()%myl), 'space')
this.put(mx, ry - 2*(rand()%myr), 'space')
}
else if(d == 1) {
this.put(lx + 2*(rand()%mxl), my, 'space')
this.put(mx, ly + 2*(rand()%myl), 'space')
this.put(mx, ry - 2*(rand()%myr), 'space')
}
else if(d == 2) {
this.put(lx + 2*(rand()%mxl), my, 'space')
this.put(rx - 2*(rand()%mxr), my, 'space')
this.put(mx, ry - 2*(rand()%myr), 'space')
}
else {
this.put(lx + 2*(rand()%mxl), my, 'space')
this.put(rx - 2*(rand()%mxr), my, 'space')
this.put(mx, ly + 2*(rand()%myl), 'space')
}
}
Chunk.prototype.generate__infmaze = function(x, y) {
// chunks are isolated at first
for(let i = 0; i < 64; i++) {
this.put(i, 0, 'wall')
this.put(0, i, 'wall')
}
// use the seed
srand((x<<15 + y) ^ seed<<3)
this.generate__infmaze_4(1, 1, 63, 63)
// break the isolation between chunks
let r1 = rand()%32
this.put(2*(rand()%32) + 1, 0, 'space')
this.put(0, 2*(rand()%32) + 1, 'space')
}
If you want to fit in the rules, simply let the s
(in f(s, x, y)
) be the seed used in srand
and cache the data generated by new Chunk().generate__infmaze
.
If you have noticed that this doesn't fit rule 1.3, you will also find it easy to fix it (change the break-the-isolation-between-chunks part, only that it may not look nice :).
Demo (seed = 0
, (0, 0)
⇒ (63, 63)
):
#############################.##################################
#.................................#.............................
#######.#########################################.##############
#...........#...#.#.#.........#.#.#.......................#.#.#.
###.#####.#.#.#.#.#.###.#####.#.#.#.#####################.#.#.#.
#.......#.#.#.#...#.#.#.#.#...#.#.#.#...#.......#.#.......#.#.#.
#####.###.###.#.#.#.#.#.#.###.#.#.#.#.###.###.###.#####.###.#.#.
#.#.#.#.#.#...#.#.#.....#.#.#.#.#.#.#.....#...............#.#...
#.#.#.#.#.#.###.#.#.###.#.#.#.#.#.#.#.#.#.###.#####.#######.#.#.
#.#.#.#.#.#.#.#.#...#...#...#...#.#.#.#.#.#.......#.........#.#.
#.#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.###########.###########.#.#.
#.#.#.#.#...#...#.#.#...#.#...#.#.#.#...................#.#.#.#.
#.#.#.#.#.#.###.#.#.#########.#.#.#.#.#.#.#####.#######.#.#.#.#.
#.#...#.#.#.#...#.#.....#.....#.#.#.#.#.#.#...........#.#.#.#.#.
#.#.#.#.#.#.#####.#########.###.#.#.#.#.#.###.###########.#.#.#.
#...#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#...#...#.....#.#.#.#.
#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#####.#.###.#.###.#.#.#.#.
#.#.#.#.#.#.#.#...#.#.#...#.#.#.#.#.#.#...#.#.........#.#.#.#.#.
#.#.#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#.###########.#.#.#.#.
#.#.#...#.#.#.#.#.#.#.#...#...#.#.#.#.#.#.#.#.............#.#.#.
#####.###.#.#.#.###.#.###.#.###.#.#.#.#.#.#####.#########.#.#.#.
#...#.#.#.#.#...#.#...#.......#.#...#...#.#.............#.#.#.#.
#.###.#.#.#.#.#.#.#.#.#.#####.#.#.#########################.#.#.
#.......#.#.#.#...#.#.#...#...#.#.#.......................#.#.#.
#.#.#.###.#.#.#.#####.#######.#.#.#######################.#.#.#.
#.#.#...#.#.#.#...#...........#.#.#...........................#.
#########.###################.#.#.###########################.##
#.......#.#.#.......#.........#.#.#.#...............#.....#.#.#.
#.#####.#.#.#.#.#######.#######.#.#.#.###############.#####.#.#.
#.#...#.#...#.#.#...#.#.#.....#.#.#.#.........#.....#.....#.....
#.#.#.#.#.#.#.#.###.#.#.#.#####.#.#.###.#########.#######.#.#.#.
#...#.#.#.#.#.#.#.#.#.........#.#.#.#.........#.....#.......#.#.
###.###.#.#.#.#.#.#.#.#.#######.#.#.###.#######.#####.#####.#.#.
#.....#.#.#.#.#.#.#.#.#.......#.#.#.................#.....#.#.#.
###.#.#.#.#.#.#.#.#.#.#.#.###.#.#.#############.#######.#####.#.
..#.#.#.#.#.#.#.#...#.#.#.#...#.#.#...#.#.#...#...#.#.....#.#.#.
#.#.#.#.#.#.#.#.###.#.#.#.#.###.#.#.#.#.#.###.#.#.#.#####.#.#.#.
#...#.#.#.#.#.#.....#.#.#.#...#.#.#.#.#.#...#...#.#.#...#.#.#.#.
#.#.#.#.#.#.#######.#########.#.#.#.#.#.#.#.#.#.#.#.#.###.#.#.#.
#.#.#.#.#.#.#.#...#.#...#.#...#.#.#.#...#.#...#.#.#.#.#.#.#.#.#.
#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.
#...#.#.#.#.#.#.#.#.#...#.#.#.#.#.#.#.....#.#.#.#.#.#...#...#.#.
#######.###.#.#.#.#.#.###.#.#.#.#.#.#.#.#.#####.#.#.#.#.#.#.#.#.
#...#.#.#.#.#...#...#.....#.#.#.#.#.#.#.#.....#.#.#.#.#.#.#.#.#.
#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.###.###.###.#.#.#.#.#.#.#.#.#.
#.#.#...#.#.#.#.#.#.#.#.#.#.#.#.#.#.#...#.#...#.#.#.#.#.#.#.#.#.
#.#.#.#.#.#.#.#.#.#.###.#####.#.#.#.#.#.###.#####.#.#.#.#.#.#.#.
#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.....#.#.#.#.#...#.#.#.
#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.###.#.#.#.#######.#.
#.#.#.#.#.#.#.#.#...#.#.#.#...#.#.#.#.#.#.#.#.#.#...#.#.#.#.#.#.
#.###.#.#.#.#####.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.
#...#.#.#.#.#...#.....#.#.#.#.#.#.#.#.#.#.......#.#.#.#.#.#.#.#.
###.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#.#.#.###########.#.#.#.#.#.#.
#.#.#.#.#.#.#.#.#.#.#.......#.#.#.#...#.#...............#.#.#.#.
#.#.#.#.#.#.#.###.#.###.#.#.#.#.#.###############.###.#.#.#.#.#.
#.....#.....#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.....#...#.#.#...#.#.#.
#######.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#######.#.#####.#.#.#.
#.....#.#.#.#.#.#.#.#...#.#.#.#...#.#.#...........#.#...#...#.#.
###.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#########.#.#.#.#.#.#.
#.......#...#.......#.#.#.#.#.#.#.#.#...#...#.......#.#...#.#.#.
#.#################################.#.###.#.#####.#.#.#.#.#.#.#.
#...............................#.#.#...#.#.#.....#.#.#.#.#.#.#.
###########################.###.#.#.#.#####.#.#####.#.#.#.#.#.#.
#.............................#...#.....#.........#.#.#.#.#.#.#.