if (typeof SoupGraph != "function") {
console.error("SoupGraph is not defined. Cannot attach a function to an undefined object!");
} else if (typeof SoupGraph.prototype.makeMaze != "undefined") {
console.error("Cannot attach the makeMaze function to SoupGraph because it is already defined!");
} else {
/**
* Turns a SoupGraph into a maze. Please note that if the graph has unidirectional edges or disconnected graphs, the maze may become unsolvable
*/
SoupGraph.prototype.makeMaze = function() {
// Get IDs of all nodes in the graph
var nodeIds = this.nodes;
// Turn the graph into a maze
(function generateMaze(self) {
// Start the generation with a random node
var nodesToProcess = [
{
node: nodeIds[Math.floor(Math.random()*nodeIds.length)],
entryEdge: null
}
];
var processed = {};
// Generate!
while (nodesToProcess.length > 0) {
// Pop a node to process
var processing = nodesToProcess.pop();
var entryEdge = processing.entryEdge;
var processing = processing.node;
// Has self cell been processed already?
if (typeof processed[processing] != "undefined")
continue;
// Mark self node as processed
processed[processing] = true;
// Find all neighbours
var edges = self.getEdgesFrom(processing);
var neighbours = {};
edges.forEach(function(edge) {
neighbours[edge.name] = edge
});
// Randomly add the neighbours to the stack
for (var i = 0; i < edges.length; i++) {
// Pick a random direction
var edgeName = (function() {
var result;
var count = 0;
for (var edgeName in neighbours) {
if (Math.random() < 1/++count)
result = edgeName;
}
return result;
})();
// Get the randomly chosen edge
var edge = neighbours[edgeName];
// Get the node in that edgeName
var nextNode = edge.toNode;
// Remove the node from the neighbours list so it is not picked again
delete neighbours[edgeName];
// Check if the neighbour has been processed
if (typeof processed[nextNode] != "undefined") {
// Get all edges in the opposite direction
var reverseEdges = self.getEdges(nextNode, processing);
if (reverseEdges.indexOf(entryEdge) >= 0)
continue;
self.removeEdge(edge);
reverseEdges.forEach(function(reverseEdge) {
self.removeEdge(reverseEdge);
});
} else {
// Push the neighbour onto the stack
nodesToProcess.push({node: nextNode, entryEdge: edge});
}
}
}
})(this);
// The graph is now a maze. Return this
return this;
};
}