Skip to content

Instantly share code, notes, and snippets.

@jurisgalang
Created July 30, 2012 16:00
Show Gist options
  • Save jurisgalang/3208024 to your computer and use it in GitHub Desktop.
Save jurisgalang/3208024 to your computer and use it in GitHub Desktop.
Maze generation using the depth-first search algorithm.
<html>
<head>
<script src="processing.js"></script>
</head>
<body>
<canvas id="maze" style="border: 2px solid #202020"></canvas>
<script type="text/javascript">
var sketch = new Processing.Sketch();
var MAXCOLS = 40;
var MAXROWS = 20;
var CELLWIDTH = parseInt(600 / MAXCOLS);
var CELLHEIGHT = parseInt(300 / MAXROWS);
sketch.attachFunction = function(p) {
p.setup = function() {
p.size(600, 300);
p.initialize();
};
p.draw = function() {
p.background(128, 128, 128);
p.generate();
for (var x = 0; x < MAXCOLS; x++) {
for (var y = 0; y < MAXROWS; y++) {
p.pushMatrix();
p.translate(x * CELLWIDTH, y * CELLHEIGHT);
p.noStroke();
cell = cells[y * MAXCOLS + x];
if (cell.visited) p.fill(255)
else p.fill(128, 128, 128);
if (cell === start) p.fill(0, 128, 0, 128)
else if (cell === current) p.fill(128, 0, 0, 128);
p.rect(0, 0, CELLWIDTH, CELLHEIGHT);
p.stroke(128, 128, 128);
p.strokeWeight(2);
for (var location in cell.walls) {
if (!cell.walls[location]) continue;
switch (location) {
case 'north':
p.line(0, 0, CELLWIDTH, 0);
break;
case 'east':
p.line(CELLWIDTH, 0, CELLWIDTH, CELLHEIGHT);
break;
case 'south':
p.line(0, CELLHEIGHT, CELLWIDTH, CELLHEIGHT);
break;
case 'west':
p.line(0, 0, 0, CELLHEIGHT);
break;
}
}
p.popMatrix();
}
}
};
var cells = new Array(MAXCOLS * MAXROWS);
var stack = new Array();
var current = null;
var start = null;
var visited = 0;
p.cell = function(x, y) {
var walls = {
north: true,
south: true,
east: true,
west: true
};
var neighbors = {
north: { x: x, y: y - 1 },
south: { x: x, y: y + 1 },
east: { x: x + 1, y: y },
west: { x: x - 1, y: y }
};
if (x === 0) neighbors.west = null
else if (x === MAXCOLS - 1) neighbors.east = null;
if (y === 0) neighbors.north = null
else if (y === MAXROWS - 1) neighbors.south = null;
var unvisitedNeighbor = function() {
var selected = null;
var unvisited = [];
for (var location in neighbors) {
if (neighbors[location] !== null) {
var cell = cells[neighbors[location].y * MAXCOLS + neighbors[location].x];
if (cell.visited) continue;
unvisited.push({ location: location, coord: neighbors[location] })
}
}
if (unvisited.length > 0) {
var i = parseInt(p.random(unvisited.length));
var neighbor = unvisited[i];
var cell = cells[neighbor.coord.y * MAXCOLS + neighbor.coord.x];
selected = { cell: cell, location: neighbor.location };
}
return selected;
};
return { x: x, y: y, walls: walls, neighbors: neighbors, visited: false, unvisitedNeighbor: unvisitedNeighbor };
};
p.initialize = function() {
for (var x = 0; x < MAXCOLS; x++) {
for (var y = 0; y < MAXROWS; y++) {
cells[y * MAXCOLS + x] = p.cell(x, y);
}
}
var x = parseInt(p.random(MAXCOLS));
var y = parseInt(p.random(MAXROWS));
start = cells[y * MAXCOLS + x];
current = start;
current.visited = true;
visited++;
};
p.generate = function() {
if (visited === MAXCOLS * MAXROWS) return;
var chosen = current.unvisitedNeighbor();
if (chosen) {
current.walls[chosen.location] = null;
stack.push(current);
current = chosen.cell;
switch (chosen.location) {
case 'north':
current.walls['south'] = null;
break;
case 'south':
current.walls['north'] = null;
break;
case 'east':
current.walls['west'] = null;
break;
case 'west':
current.walls['east'] = null;
break;
}
current.visited = true;
visited++;
} else {
current = stack.pop();
}
}
};
var canvas = document.getElementById("maze");
var processing = new Processing(canvas, sketch);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment