Skip to content

Instantly share code, notes, and snippets.

@bouk
Forked from mbostock/.block
Last active August 29, 2015 14:00
Show Gist options
  • Save bouk/11202729 to your computer and use it in GitHub Desktop.
Save bouk/11202729 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: #000;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
cellSize = 4,
cellWidth = Math.ceil(width / cellSize),
cellHeight = Math.ceil(height / cellSize);
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
context.fillStyle = "white";
var maze = d3.range(cellHeight * cellWidth).map(function() { return 1; }),
frontier = [];
addToMaze(1, cellHeight - 2);
addToFrontier(2, cellHeight - 2);
addToFrontier(1, cellHeight - 3);
d3.timer(function() {
for (var i = 0; i < 100; ++i) {
if (exploreFrontier()) {
return true;
}
}
});
function fillCell(i) {
context.fillRect((i % cellWidth) * cellSize, (i / cellWidth | 0) * cellSize, cellSize, cellSize);
}
function clearCell(i) {
context.clearRect((i % cellWidth) * cellSize, (i / cellWidth | 0) * cellSize, cellSize, cellSize);
}
function index(x, y) {
return y * cellWidth + x;
}
function addToMaze(x, y) {
var i = index(x, y);
maze[i] = 0;
fillCell(i);
}
function addToFrontier(x, y) {
var i = index(x, y);
if (!maze[i]) return;
fillCell(i);
frontier.push(i);
}
function removeFromFrontier() {
if (!frontier.length) return null;
var index = Math.random() * frontier.length | 0;
var i = frontier[index];
frontier[index] = frontier[frontier.length - 1];
frontier.pop()
clearCell(i);
return i;
}
function exploreFrontier() {
var i = removeFromFrontier();
if (i == null) return true;
var x = i % cellWidth,
y = i / cellWidth | 0,
ox,
oy,
oi = x > 0 && !maze[index(x - 1, y)] ? (x < cellWidth - 1 ? index(ox = x + 1, oy = y) : NaN)
: x < cellWidth - 1 && !maze[index(x + 1, y)] ? (x > 0 ? index(ox = x - 1, oy = y) : NaN)
: y > 0 && !maze[index(x, y - 1)] ? (y < cellHeight - 1 ? index(ox = x, oy = y + 1) : NaN)
: y < cellHeight - 1 && !maze[index(x, y + 1)] ? (y > 0 ? index(ox = x, oy = y - 1) : NaN)
: NaN;
if (maze[oi]) { // opposite cell is filled
addToMaze(x, y);
var inside = true;
context.fillStyle = "magenta";
if (ox > 0) addToFrontier(ox - 1, oy); else inside = false;
if (ox < cellWidth - 1) addToFrontier(ox + 1, oy); else inside = false;
if (oy > 0) addToFrontier(ox, oy - 1); else inside = false;
if (oy < cellHeight - 1) addToFrontier(ox, oy + 1); else inside = false;
context.fillStyle = "white";
if (inside) addToMaze(ox, oy);
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment