A simple random maze generator, using the Recursive Division method described on Wikipedia. The code was hand-tuned for size (which mostly involved extracting common sub-expressions and removing edge-…
a='(1(@i=40,e=document.getElementById("c");D=64HD=DN9=48H9=9Ne=e.getContext("2d");(new (1(u,w){1 r(a,c){return Lound(Landom()*(a-c*2)/i)*i+c}1 p(aO,k,n,o,f,g,b@dRk,iJb&&!(j<i*23b-nQ3b-fQ)@qRk,l5,c,b,k,b>n?nAq,b>f?fAg5+bO-b,k,b<n?n-bAo,b<f?f-bAq)}else if(k<i*23d-gQ3d-oQ)v.push(this);else{qRj,l);bRj,i5O,d,n,d>o?oAq,d>g?gAb5,c+d,j,k-d,q,d<o?o-dAf,d<g?g-dAb)}Fm@s=-l+h,x=c+g,t=c+k,y=a+f;m7a,c-hJg){m%a,x+s);m7a,x-s)}m%a,tJf){m%y+s,t);m7y-s,t)}m%a+j+h,t)}}var v=[],h=2,l=i/2;new p(h,h,u-4,w-4K,0);Fa){a.lineWidth=4;a.beginPath();for(var c=0;c<v.length;c++)v[c].a(a);a7-hGh);a%u,w);a.stroke()}})(640,480)).a(e)})();';b='.lineTo(#%#function#1#||Math.abs(#3#);new p(a#5#.moveTo(#7#e.height#9#){var #@#:0,#A#e.width#D#this.a=1(#F#,h);a%u,#G#4;e.styl#H#);if(#J#,0,0,0#K#Math.r#L#+"px";#N#,c,j#O#)<l#Q#=r(#R'.split('#');for(i=37;i>0;i-=2){a=a.replace(RegExp(b[i],'g'),b[i-1]);}eval(a);
YT0nKDEoQGk9NDAsZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYyIpO0Q9NjRIRD1ETjk9NDhIOT05TmU9ZS5nZXRDb250ZXh0KCIyZCIpOyhuZXcgKDEodSx3KXsxIHIoYSxjKXtyZXR1cm4gTG91bmQoTGFuZG9tKCkqKGEtYyoyKS9pKSppK2N9MSBwKGFPLGssbixvLGYsZyxiQGRSayxpSmImJiEoajxpKjIzYi1uUTNiLWZRKUBxUmssbDUsYyxiLGssYj5uP25BcSxiPmY/ZkFnNStiTy1iLGssYjxuP24tYkFvLGI8Zj9mLWJBcSl9ZWxzZSBpZihrPGkqMjNkLWdRM2Qtb1Epdi5wdXNoKHRoaXMpO2Vsc2V7cVJqLGwpO2JSaixpNU8sZCxuLGQ+bz9vQXEsZD5nP2dBYjUsYytkLGosay1kLHEsZDxvP28tZEFmLGQ8Zz9nLWRBYil9Rm1Acz0tbCtoLHg9YytnLHQ9YytrLHk9YStmO203YSxjLWhKZyl7bSVhLHgrcyk7bTdhLHgtcyl9bSVhLHRKZil7bSV5K3MsdCk7bTd5LXMsdCl9bSVhK2oraCx0KX19dmFyIHY9W10saD0yLGw9aS8yO25ldyBwKGgsaCx1LTQsdy00SywwKTtGYSl7YS5saW5lV2lkdGg9NDthLmJlZ2luUGF0aCgpO2Zvcih2YXIgYz0wO2M8di5sZW5ndGg7YysrKXZbY10uYShhKTthNy1oR2gpO2EldSx3KTthLnN0cm9rZSgpfX0pKDY0MCw0ODApKS5hKGUpfSkoKTsnO2I9Jy5saW5lVG8oIyUjZnVuY3Rpb24jMSN8fE1hdGguYWJzKCMzIyk7bmV3IHAoYSM1Iy5tb3ZlVG8oIzcjZS5oZWlnaHQjOSMpe3ZhciAjQCM6MCwjQSNlLndpZHRoI0QjdGhpcy5hPTEoI0YjLGgpO2EldSwjRyM0O2Uuc3R5bCNIIyk7aWYoI0ojLDAsMCwwI0sjTWF0aC5yI0wjKyJweCI7I04jLGMsaiNPIyk8bCNRIz1yKCNSJy5zcGxpdCgnIycpO2ZvcihpPTM3O2k+MDtpLT0yKXthPWEucmVwbGFjZShSZWdFeHAoYltpXSwnZycpLGJbaS0xXSk7fWV2YWwoYSk7
//copyright 2010 Nick Lockwood
//-----------------------------------------------
//maze generator source
//-----------------------------------------------
(function() {
function Maze(width, height) {
//maze
var chambers = [];
var e2 = EDGE/2;
var c2 = CELL_SIZE/2;
//random position
function pointInRange(max, min) {
return Math.round((Math.random()*(max - min*2))/CELL_SIZE)*CELL_SIZE + min;
}
//chamber
function Chamber(x, y, width, height, topDoor, rightDoor, bottomDoor, leftDoor, splitX) {
function canSplit(size, split, door1, door2) {
return !(size < CELL_SIZE*2 || Math.abs(split - door1) < c2 || Math.abs(split - door2) < c2);
}
function splitAfterDoor(split, door) {
return (split > door)? door: 0;
}
function splitBeforeDoor(split, door) {
return (split < door)? door - split: 0;
}
var splitY = pointInRange(height, CELL_SIZE);
//split chamber
if (splitX && canSplit(width, splitX, topDoor, bottomDoor)) {
var join = pointInRange(height, c2);
new Chamber(x, y, splitX, height,
splitAfterDoor(splitX, topDoor), join,
splitAfterDoor(splitX, bottomDoor), leftDoor);
new Chamber(x + splitX, y, width - splitX, height,
splitBeforeDoor(splitX, topDoor), rightDoor,
splitBeforeDoor(splitX, bottomDoor), join);
} else if (canSplit(height, splitY, leftDoor, rightDoor)) {
var join = pointInRange(width, c2);
var splitX = pointInRange(width, CELL_SIZE);
new Chamber(x, y, width, splitY,
topDoor, splitAfterDoor(splitY, rightDoor),
join, splitAfterDoor(splitY, leftDoor),
splitX);
new Chamber(x, y + splitY, width, height - splitY,
join, splitBeforeDoor(splitY, rightDoor),
bottomDoor, splitBeforeDoor(splitY, leftDoor),
splitX);
} else {
chambers.push(this);
}
//draw chamber
this.draw = function(ctx) {
//common sub-expressions
var a = - c2 + e2;
var b = y + leftDoor;
var c = y + height;
var d = x + bottomDoor;
//draw left wall
ctx.moveTo(x, y - e2);
if (leftDoor) {
ctx.lineTo(x, b + a);
ctx.moveTo(x, b - a);
}
ctx.lineTo(x, c);
//draw bottom wall
if (bottomDoor) {
ctx.lineTo(d + a, c);
ctx.moveTo(d - a, c);
}
ctx.lineTo(x + width + e2, c);
}
}
//create chambers
new Chamber(e2, e2, width - EDGE, height - EDGE, 0, 0, 0, 0);
this.draw = function(ctx) {
ctx.lineWidth = EDGE;
ctx.beginPath();
for (var i = 0; i < chambers.length; i++) {
chambers[i].draw(ctx);
}
ctx.moveTo(-e2, e2);
ctx.lineTo(width, e2);
ctx.lineTo(width, height);
ctx.stroke();
}
}
//config
var MAZE_WIDTH = 640;
var MAZE_HEIGHT = 480;
var EDGE = 4;
var CELL_SIZE = 40;
//canvas
var cvs = document.getElementById('c');
cvs.width = MAZE_WIDTH + EDGE;
cvs.style.width = cvs.width + 'px';
cvs.height = MAZE_HEIGHT + EDGE;
cvs.style.height = cvs.height + 'px';
var ctx = cvs.getContext('2d');
//maze
var maze = new Maze(MAZE_WIDTH, MAZE_HEIGHT);
maze.draw(ctx);
})();
//-----------------------------------------------
//packer (includes closure-compiled maze source)
//-----------------------------------------------
<!DOCTYPE html>
<html>
<head>
<title>Packer</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
<textarea id="input" style="width:600px;height:200px;">(function(){var i=40,e=document.getElementById("c");e.width=644;e.style.width=e.width+"px";e.height=484;e.style.height=e.height+"px";e=e.getContext("2d");(new (function(u,w){function r(a,c){return Math.round(Math.random()*(a-c*2)/i)*i+c}function p(a,c,j,k,n,o,f,g,b){var d=r(k,i);if(b&&!(j<i*2||Math.abs(b-n)<l||Math.abs(b-f)<l)){var q=r(k,l);new p(a,c,b,k,b>n?n:0,q,b>f?f:0,g);new p(a+b,c,j-b,k,b<n?n-b:0,o,b<f?f-b:0,q)}else if(k<i*2||Math.abs(d-g)<l||Math.abs(d-o)<l)v.push(this);else{q=r(j,l);b=r(j,i);new p(a,c,j,d,n,d>o?o:0,q,d>g?g:0,b);new p(a,c+d,j,k-d,q,d<o?o-d:0,f,d<g?g-d:0,b)}this.a=function(m){var s=-l+h,x=c+g,t=c+k,y=a+f;m.moveTo(a,c-h);if(g){m.lineTo(a,x+s);m.moveTo(a,x-s)}m.lineTo(a,t);if(f){m.lineTo(y+s,t);m.moveTo(y-s,t)}m.lineTo(a+j+h,t)}}var v=[],h=2,l=i/2;new p(h,h,u-4,w-4,0,0,0,0);this.a=function(a){a.lineWidth=4;a.beginPath();for(var c=0;c<v.length;c++)v[c].a(a);a.moveTo(-h,h);a.lineTo(u,h);a.lineTo(u,w);a.stroke()}})(640,480)).a(e)})();</textarea>
<br>
<button id="pack">Pack</button>
<br>
<textarea id="output" style="width:600px;height:200px;"></textarea>
<br>
<input id="size">
<script>
function escapeRegex(text) {
return text.replace(/([.?()|+*/]|\\|\[|\])/g, '\\$1');
}
document.getElementById('pack').onclick = function() {
var input = document.getElementById('input').value;
var output = input.replace(/\n/g,'');
output = output.replace(/^\(function\(\){var /,'').replace(/}\)\(\);$/,'');
var output = input;
var strings = [];
var used = [];
//get unused chars for use as keys
var chars = [];
for (var i = 32; i < 127; i++) {
var char = String.fromCharCode(i);
if (char != '"' && char != '\\' && char != "'" && !output.match(new RegExp(escapeRegex(char),'g'))) {
chars.push(char);
}
}
//get common strings
function getStrings() {
var commonStrings = {};
for (var i = 3; i < 50; i++) {
for (var j = 0; j < output.length - i + 1; j++) {
var s = output.substr(j, i);
if (!commonStrings[s]) {
commonStrings[s] = 1;
} else {
commonStrings[s] ++;
}
}
}
strings = [];
for (i in commonStrings) {
if (i.length*commonStrings[i] > commonStrings[i] + i.length + 3) {
strings.push([i, commonStrings[i]]);
}
}
return strings.length;
}
//process common strings to get best saver
function process() {
if (strings.length > 0) {
//sort
strings.sort(function(a,b) {
return (a[0].length * a[1] < b[0].length * b[1])? 1: -1;
});
//get best
var best = strings.shift()[0];
var replacement = chars[used.length + 1];
used.push(best);
best = escapeRegex(best);
//replace in output
output = output.replace(new RegExp(best, 'g'), replacement);
}
}
var keys = [];
for(var i = 1; i < chars.length && getStrings(); i++) {
process();
keys.push(used[i-1]);
keys.push(escapeRegex(chars[i]));
}
output = "a='" + output + "';b='" + keys.join(chars[0]) + "'.split('" + chars[0] + "');for(i=" + (keys.length-1) + ";i>0;i-=2){a=a.replace(RegExp(b[i],'g'),b[i-1]);}eval(a);"
document.getElementById('output').value = output;
document.getElementById('size').value = input.length + ' -> ' + output.length;
}
</script>
</body>
</html>