Skip to content

Instantly share code, notes, and snippets.

@xav76
Created October 24, 2012 16:50
Show Gist options
  • Save xav76/3947280 to your computer and use it in GitHub Desktop.
Save xav76/3947280 to your computer and use it in GitHub Desktop.
A CodePen by Marek Bielańczuk. Maze Generator - Using Prim's algorithm where weight of adjacent edges is set with random numbers.
<div id="panel">
<div id="right">
<div id="caption">
Maze generator
</div>
<div id="desc">
Using Prim's algorithm where weight of adjacent edges is set with random numbers.
</div>
<div id="buttons">
<a class="button disable" id="btStart" href="javascript://">Start</a>
<a class="button disable" id="btStop" href="javascript://">Stop</a>
<a class="button disable" id="btClear" href="javascript://">Clear</a>
</div>
</div>
<div id="left">
<div id="canvas"></div>
</div>
</div>
jQuery(function() {
$.getScript("http://www.html5canvastutorials.com/libraries/kinetic-v3.10.4.js", function(data, textStatus, jqxhr) {
// console.log(data);
// console.log(textStatus);
// console.log(jqxhr.status);
mazeGen.init();
$("#btStart").click(function() {
if (!$("#btStart").hasClass("disable"))
{
$("#btStart").addClass("disable");
$("#btStop").removeClass("disable");
$("#btClear").addClass("disable");
mazeGen.start();
}
});
$("#btStart").toggleClass("disable");
$("#btStop").click(function() {
if (!$("#btStop").hasClass("disable")) {
$("#btStart").removeClass("disable");
$("#btStop").addClass("disable");
$("#btClear").removeClass("disable");
mazeGen.stop();
}
});
$("#btClear").click(function() {
if (!$("#btClear").hasClass("disable"))
mazeGen.clear();
});
});
Array.prototype.contains = function(idx) {
var fIdx = -1;
for(var i = 0; i < this.length; i++) {
if(this[i].idx == idx) {
fIdx = i;
break;
}
}
return fIdx;
}
Array.prototype.getByIndex = function(idx) {
var obj = null;
for(var i = 0; i < this.length; i++) {
if(this[i].idx == idx) {
obj = this[i];
break;
}
}
return obj;
}
Array.prototype.clearAll = function() {
this.splice(0,this.length);
}
var elemShape = function(aX, aY) {
return new Kinetic.Rect({
x : aX,
y : aY,
width : 10,
height : 10,
fill : "transparent",
stroke : "transparent",
strokeWidth : 0
});
}
/* *** */
var mazeGen = {
interval: null,
stage: null,
layer: null,
vertex: new Array(),
adjacent: new Array(),
emptyBox: new Array(),
intervalSwitch: true,
adjCurr: new Array(),
v: null,
a: null,
color1: "#FA7000",
color2: "#ddd",
generateGraph: function() {
var w = 57;
var h = 17;
for(var r = 0; r < h; r++)
for(var c = 0; c < w; c++) {
var vIdx = r * w + c;
if($.inArray(vIdx, mazeGen.emptyBox) > -1) {
mazeGen.layer.add(elemShape(c * 10, r * 10));
} else if(mazeGen.adjacent.contains(vIdx) == -1) {
var v = {
shape : elemShape(c * 10, r * 10),
idx : vIdx,
adj : new Array()
};
for( ar = r - 1; ar < r + 2; ar++)
for( ac = c - 1; ac < c + 2; ac++) {
var aIdx = ar * w + ac;
if(aIdx == v.idx)
continue;
if((ac < 0) || (ar < 0) || (ac >= w) || (ar >= h))
continue;
if((ac != c) && (ar != r)) {
mazeGen.emptyBox[mazeGen.emptyBox.length] = aIdx;
continue;
}
v.adj[v.adj.length] = aIdx;
var aPos = mazeGen.adjacent.contains(aIdx);
if(aPos == -1) {
var adj = {
idx : aIdx,
shape : elemShape(ac * 10, ar * 10),
w : Math.floor(Math.random() * 11),
v1 : vIdx
};
mazeGen.adjacent[mazeGen.adjacent.length] = adj;
mazeGen.layer.add(adj.shape);
} else {
mazeGen.adjacent[aPos].v2 = vIdx;
}
}
mazeGen.vertex[mazeGen.vertex.length] = v;
mazeGen.layer.add(v.shape);
}
}
},
generateMaze: function() {
if(mazeGen.vertex.length <= 1) {
clearInterval(mazeGen.interval);
$("#btStart").removeClass("disable");
$("#btStop").addClass("disable");
$("#btClear").removeClass("disable");
mazeGen.a.shape.setFill(mazeGen.color2);
mazeGen.vertex[0].shape.setFill(mazeGen.color2);
mazeGen.layer.draw();
return;
}
mazeGen.v.shape.setFill(mazeGen.color1);
if(mazeGen.a)
mazeGen.a.shape.setFill(mazeGen.color2);
mazeGen.layer.draw();
if(mazeGen.intervalSwitch) {
mazeGen.intervalSwitch = false;
return;
}
for( s = 0; s < mazeGen.v.adj.length; s++) {
if(mazeGen.adjacent.contains(mazeGen.v.adj[s]) > -1)
mazeGen.adjCurr[mazeGen.adjCurr.length] = mazeGen.adjacent.getByIndex(mazeGen.v.adj[s]);
}
mazeGen.v.shape.setFill(mazeGen.color2);
var tmp = mazeGen.vertex.splice(mazeGen.vertex.contains(mazeGen.v.idx), 1);
if((mazeGen.vertex.length > 0) && (mazeGen.adjacent.length > 0)) {
mazeGen.adjCurr.sort(function(pa, pb) {
return pa.w - pb.w
});
for(var ac = 0; ac < mazeGen.adjCurr.length; ac++) {
var v1 = mazeGen.adjCurr[ac].v1;
var v2 = mazeGen.adjCurr[ac].v2;
var cv1 = (mazeGen.vertex.contains(v1) > -1);
var cv2 = (mazeGen.vertex.contains(v2) > -1);
if(cv1 || cv2) {
mazeGen.v = mazeGen.vertex.getByIndex([( cv1 ? mazeGen.adjCurr[ac].v1 : mazeGen.adjCurr[ac].v2)]);
mazeGen.adjCurr[ac].shape.setFill(mazeGen.color1);
mazeGen.a = mazeGen.adjCurr[ac];
mazeGen.layer.draw();
mazeGen.adjacent.splice(mazeGen.adjacent.contains(mazeGen.adjCurr[ac].idx), 1)
mazeGen.adjCurr.splice(ac, 1);
break;
}
}
}
mazeGen.intervalSwitch = true;
},
init: function() {
mazeGen.stage = new Kinetic.Stage({
container : "canvas",
width : 590,
height : 190
});
mazeGen.layer = new Kinetic.Layer();
mazeGen.stage.add(mazeGen.layer);
mazeGen.generateGraph();
mazeGen.v = mazeGen.vertex[0];
mazeGen.a = null;
},
clear: function() {
mazeGen.layer.removeChildren();
mazeGen.stage.clear();
mazeGen.vertex.clearAll();
mazeGen.adjacent.clearAll();
mazeGen.emptyBox.clearAll();
mazeGen.intervalSwitch = true;
mazeGen.adjCurr.clearAll();
mazeGen.generateGraph();
mazeGen.v = mazeGen.vertex[0];
mazeGen.a = null;
},
start: function() {
mazeGen.interval = setInterval(function() {
mazeGen.generateMaze();
}, 50);
},
stop: function() {
clearInterval(mazeGen.interval);
}
} // genMaze
});
@import url(http://fonts.googleapis.com/css?family=Alfa+Slab+One);
body {
background-color: #787878;
background: #333 url(http://codepen.io/images/classy_fabric.png);
}
#panel {
width: 920px;
height: 190px;
position: relative;
margin: 10px auto;
}
#right {
width: 300px;
height: 190px;
position: relative;
float: right;
margin-top: 10px;
}
#caption {
width: 100%;
font-family: 'Alfa Slab One', Arial;
font-weight: normal;
font-size: 32px;
color: #DDD;
text-align: center;
text-shadow: 0px 0px 5px #222;
text-transform: uppercase;
line-height: 35px;
margin-bottom: 10px;
}
#desc {
width: 270px;
font-family: Arial;
font-size: 12px;
color: #DDD;
text-align: center;
text-shadow: 0px 0px 5px #111;
margin: 0 20px 0 20px;
}
#canvas {
width: 590px;
height: 190px;
margin: 10px;
}
#buttons {
width: 310px;
text-align: center;
margin-top: 10px;
}
#left {
width: 590px;
height: 190px;
margin: 10px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #000;
-moz-box-shadow: 0 1px 3px #000;
border-top: 1px solid #555;
box-shadow: 0 1px 3px #000;
background: -webkit-linear-gradient(#444, #333);
background: -moz-linear-gradient(#444, #333);
background: -o-linear-gradient(#444, #333);
background: -ms-linear-gradient(#444, #333);
background: linear-gradient(#444, #333);
position: relative;
float: left;
}
a:link, a:visited, a:active {
text-decoration: none;
}
a:hover {
color: #FA7000;
}
.button {
display: inline-block;
font-family: Arial;
font-size: 14px;
font-weight: bold;
color: #333;
text-align: center;
width: 85px;
line-height: 40px;
margin: 10px 2px 10px 2px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #000;
-moz-box-shadow: 0 1px 3px #000;
border-top: 1px solid #fff;
box-shadow: 0 2px 4px #000;
background: -webkit-linear-gradient(#ededed, #ddd);
background: -moz-linear-gradient(#ededed, #ddd);
background: -o-linear-gradient(#ededed, #ddd);
background: -ms-linear-gradient(#ededed, #ddd);
background: linear-gradient(#ededed, #ddd);
}
.disable {
color: #999;
border-top: 1px solid #bbb;
background: -webkit-linear-gradient(#aaa, #bbb);
background: -moz-linear-gradient(#aaa, #bbb);
background: -o-linear-gradient(#aaa, #bbb);
background: -ms-linear-gradient(#aaa, #bbb);
background: linear-gradient(#aaa, #bbb);
}
a:hover.disable {
color: #999;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment