Last active
January 14, 2022 12:41
-
-
Save XWolfOverride/dad15edd8d3d966917e713e0f84f2761 to your computer and use it in GitHub Desktop.
Maze generator and resolvers in JS / HTML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Mz</title> | |
<style> | |
table { | |
border-spacing: 0; | |
border-collapse: spaced; | |
} | |
td { | |
width: 10px; | |
height: 10px; | |
box-sizing: border-box; | |
} | |
td:hover { | |
border: 3px solid cornflowerblue !important; | |
} | |
html, | |
body { | |
margin: 0; | |
} | |
#toolbar { | |
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; | |
font-size: 12px; | |
font-weight: bold; | |
background-color: lightgrey; | |
box-shadow: 0 2px 5px lightgrey; | |
} | |
#maze { | |
margin: 10px; | |
} | |
</style> | |
<script> | |
ssz = 5; | |
if (!Object.prototype.merge) | |
Object.defineProperty(Object.prototype, "merge", { | |
writable: true, | |
value: function (src) { | |
if (!src) | |
return this; | |
for (var key in src) | |
this[key] = src[key]; | |
return this; | |
} | |
}); | |
function rnd(max) { | |
return Math.trunc(Math.random() * max); | |
} | |
function Maze(w, h) { | |
var tbl = document.createElement("table"); | |
if (w > 0 && h > 0 && (w > 1 || h > 1)) { | |
tbl.c = []; | |
function cell(x, y) { | |
if (x < 0 || y < 0 || x >= w || y >= h) | |
return null; | |
return tbl.c[y][x]; | |
} | |
// Build table body | |
for (var y = 0; y < h; y++) { | |
var tr = document.createElement("tr"); | |
tbl.c[y] = []; | |
for (var x = 0; x < w; x++) { | |
var td = document.createElement("td"); | |
tbl.c[y][x] = td; | |
td.merge({ | |
x: x, | |
y: y, | |
_step: 0 | |
}) | |
tr.appendChild(td); | |
td.addEventListener('contextmenu', function (ev) { | |
ev.preventDefault(); | |
tbl.end = this; | |
stylice(); | |
return false; | |
}, false); | |
td.addEventListener('click', function (ev) { | |
ev.preventDefault(); | |
tbl.start = this; | |
stylice(); | |
resolveMaze(1); | |
return false; | |
}, false); | |
} | |
tbl.appendChild(tr); | |
} | |
// Create entry/exit and container wall | |
if (rnd(2) == 0) | |
tbl.start = tbl.c[rnd(h)][rnd(2) * (w - 1)]; | |
else | |
tbl.start = tbl.c[rnd(2) * (h - 1)][rnd(w)]; | |
while (!tbl.end || tbl.end == tbl.start) { | |
if (rnd(2) == 0) | |
tbl.end = tbl.c[rnd(h)][rnd(2) * (w - 1)]; | |
else | |
tbl.end = tbl.c[rnd(2) * (h - 1)][rnd(w)]; | |
} | |
// Maze | |
function MazeTail(c) { | |
c.style.backgroundColor = "red"; | |
c._done = true; | |
var n, d, ttl; | |
ttl = 20; | |
while (ttl-- > 0) { | |
d = rnd(4); | |
switch (d) { | |
case 0: | |
n = cell(c.x, c.y - 1); | |
break; | |
case 1: | |
n = cell(c.x + 1, c.y); | |
break; | |
case 2: | |
n = cell(c.x, c.y + 1); | |
break; | |
case 3: | |
n = cell(c.x - 1, c.y); | |
break; | |
} | |
if (n && !n._done) { | |
n.style.backgroundColor = "blue"; | |
switch (d) { | |
case 0: | |
c._u = n; | |
n._d = c; | |
break; | |
case 1: | |
c._r = n; | |
n._l = c; | |
break; | |
case 2: | |
c._d = n; | |
n._u = c; | |
break; | |
case 3: | |
c._l = n; | |
n._r = c; | |
break; | |
} | |
MazeTail(n); | |
} | |
} | |
} | |
MazeTail(tbl.start); | |
// Stylice table | |
function stylice() { | |
for (var y = 0; y < h; y++) { | |
for (var x = 0; x < w; x++) { | |
var c = tbl.c[y][x]; | |
c._step = 0; | |
c.style.cssText = null; | |
if (!c._u) | |
c.style.borderTop = "1px solid black"; | |
if (!c._d) | |
c.style.borderBottom = "1px solid black"; | |
if (!c._l) | |
c.style.borderLeft = "1px solid black"; | |
if (!c._r) | |
c.style.borderRight = "1px solid black"; | |
if (!c._done) | |
c.style.backgroundColor = "black"; | |
} | |
} | |
tbl.start.style.backgroundColor = "#AFA"; | |
tbl.end.style.backgroundColor = "#FAA"; | |
} | |
stylice(); | |
} | |
// public members | |
this.table = tbl; | |
this.stylice = stylice; | |
} | |
function MazeMinner(m, pt, anim, onend) { | |
m.stylice(); | |
var c = m.table.start, steps = 0; | |
function step() { | |
// step control | |
steps++; | |
if (pt) | |
pt.innerHTML = steps; | |
if (c == m.table.end) { | |
c.style.backgroundColor = "#5F5"; | |
if (onend) | |
onend(); | |
return; | |
} | |
// decide direction | |
var lvl, dirs = [c._r, c._l, c._d, c._u], nc; | |
for (lvl = 0; lvl <= 1; lvl++) { | |
for (i in dirs) { | |
cl = dirs[i]; | |
if (cl && cl._step == lvl) { | |
nc = cl; | |
break | |
} | |
} | |
if (nc) | |
break; | |
} | |
if (!nc) { | |
c.style.backgroundColor = "red"; | |
if (pt) | |
pt.innerHTML = "Error (" + steps + ")"; | |
if (onend) | |
onend(); | |
return; | |
} | |
// mark | |
c._step = nc._step + 1; | |
if (c != m.table.start) | |
c.style.backgroundColor = "#" + ["fff", "66a", "fee"][c._step]; | |
// next step | |
c = nc; | |
if (anim) | |
setTimeout(step); | |
else | |
return true; | |
} | |
if (anim) | |
step(); | |
else while (step()); | |
} | |
function createMaze() { | |
var w = Number(document.getElementById("mw").value); | |
var h = Number(document.getElementById("mh").value); | |
if (window.mz) | |
document.getElementById("maze").removeChild(window.mz.table); | |
window.mz = new Maze(w, h); | |
document.getElementById("maze").appendChild(window.mz.table); | |
} | |
function resolveMaze(mm) { | |
if (!window.mz) | |
return; | |
var anim = document.getElementById("anim").checked; | |
new MazeMinner(window.mz, document.getElementById("mm"), anim); | |
} | |
</script> | |
</head> | |
<body onload="createMaze()"> | |
<div id="toolbar"> | |
Size | |
<input id="mw" type="number" value="20" width="10px" onchange="createMaze()"> x | |
<input id="mh" type="number" value="20" width="10px" onchange="createMaze()">, | |
<input type="button" value="Create" onclick="createMaze()"> | |
<input id="anim" type="checkbox">Animate | |
<input type="button" value="Resolve" onclick="resolveMaze()"> steps: | |
<span id="mm"></span> | |
</div> | |
<div id="maze"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you show me a picture of what it looks like?