People like Ben Forta may rave about so called "important" ColdFusion features like Excel generation, .Net integration, and PDF Manipulation, but honestly, how important are those features in comparison to something really in demand in today's enterprise market: Maze Generation. I can't tell you how many times clients have asked me to generate mazes for them - sometimes even removing less critical items from the contract like performance tuning and security reviews. So with that in mind, last night I wrote a ColdFusion port of Emanuele Feronato's PHP code to generate mazes. You can find her blog entry here.
The port was pretty simple. ColdFusion supports variables with dollar signs in front, but they drive me crazy when I look at them. I mean, would you want code that looks like this?
<cfoutput>#$x#</cfoutput>
So I rewrote her variables to get rid of the dollar signs. I also had to deal with the fact that PHP incorrectly uses 0-based array indexes. (Ok, I know, I know, but go with me here.) PHP also, and this is truly odd, will blissfully ignore you trying to access an index in an array that doesn't exist, like -1. Oh I got warnings, but no real errors. I'm not sure what the logic of that is (maybe PHPs coders can't count? I kid!). With that said, here is the completed code. Again, credit goes to Emanuele.
<cfscript>
mazeWidth = 30;
mazeHeight = 30;
maze = arrayNew(2);
moves = [];
width = 2mazeWidth+1;
height = 2mazeHeight+1;
for(x=1;x<=height;x++) {
for(y=1;y<=width;y++){
maze[x][y]=1;
}
}
xPos = 2;
yPos = 2;
maze[xPos][yPos]=0;
moves[1] = yPos+(xPos*width);
while(arrayLen(moves)) {
possibleDirections = "";
if(arrayLen(maze) gte xPos+2 && maze[xPos+2][yPos] == 1 && xPos+2!=0 && xPos+2!=height-0){
possibleDirections &= "S";
}
if(xpos-2 gt 0 && maze[xPos-2][yPos]==1 && xPos-2!=0 && xPos-2!=height-0){
possibleDirections &= "N";
}
if(ypos-2 gt 0 && maze[xPos][yPos-2]==1 && yPos-2!=0 && yPos-2!=width-0){
possibleDirections &= "W";
}
if(arrayLen(maze[xPos]) gte yPos+2 && maze[xPos][yPos+2]==1 && yPos+2!=0 && yPos+2!=width-0) {
possibleDirections &= "E";
}
if(len(possibleDirections)) {
move = randRange(1,len(possibleDirections));
switch (mid(possibleDirections, move, 1)){
case "N": maze[xPos-2][yPos]=0;
maze[xPos-1][yPos]=0;
xPos -=2;
break;
case "S": maze[xPos+2][yPos]=0;
maze[xPos+1][yPos]=0;
xPos +=2;
break;
case "W": maze[xPos][yPos-2]=0;
maze[xPos][yPos-1]=0;
yPos -=2;
break;
case "E": maze[xPos][yPos+2]=0;
maze[xPos][yPos+1]=0;
yPos +=2;
break;
}
moves[arrayLen(moves)+1] = yPos + (xPos*width);
}
else {
back = moves[arrayLen(moves)];
arrayDeleteAt(moves, arrayLen(moves));
xPos = fix(back/width);
Ypos = back mod width;
}
}
// drawing the maze
writeOutput("<code style='font-size:10px;line-height:8x'>");
for(x=1;x<=height;x++){
for(y=1;y<=width;y++){
if(maze[x][y]==1){
writeOutput("##");
}
else {
writeOutput(" ");
}
}
writeOutput("<br>");
}
writeOutput("
");
And an example of the output:

You can run a demo of this yourself here. Note that every reload generates a new and random maze. To be honest, I do have kind of a cool idea of something to do with this, but I'm waiting to see if I can get it done for Demomania at CFUNITED.
Archived Comments
Where are the entry and exit points?
Upper left for entry, bottom right for ext.
Ray, if you used a fixed width font such as courier, you could get a maze that was actually a square. Just a thought.
I added font-family:courier to the code style in the demo code, but it didn't seem to do anything.
this kind of uselessness is refreshing!
REALLY liking the new look/feel of the blog
this is way better than the new ORM features in CF 9
Very Clever....and DIG the new look/feel
I suggest adding <cfmaze> support to CF9... something like <cfmaze width=".." height=".." wallChar=".." /> would do.. :)
PS: being Emanuele italian, I suppose you should use "he/him".. I know the long hair in the blog's cartoon can be misleading ;)
now write an app that solves it :)
@Ludovico: Ouch - If I misgendered him, I'm definitely sorry!
I'm lost....
Finally some real enterprise features that I can use!
If you put a <pre> around it, add <cfprocessingdirective pageencoding="utf-8"> and use ? (UTF U+2588) as the block instead of ## it looks awesome!
FYI, looks like code format on the blog is a bit off. Tabs aren't showing up. Will fix.... some time.
As always - the JediMaster never ceases to a-maze me... {grin}
Ray...
Change this line:
<code style='font-size:10px;line-height:8x'>
to this:
<code style='font-family: courier;letter-spacing: .3em;font-size:10px;line-height:8x'>
And the display will be much better.
Wow, this is rather interesting! Pretty complicated too. Did you understand the code ray or simply ported it to CF?
You da' man!
No, I don't get it. I tried... and I kind of think I get some of the logic, but it is definitely a bit above me. I have a healthy respect for algorithms like this. It's like art.
SWEET!!!
I had to change:
}
else {
writeOutput(" ");
}
}
to:
}
else {
writeOutput(" ");
}
}
To get it to work... and now that I've got it working the rest of my day is a write off.
Ah, my &_nbsp_; didn't show up in your comments... and hence your code posting -- ma' bad :)
Ray my tummy hurts...
But your blog made it feel better. I really like the new blog... I found a couple errors using IE6 but no one should use IE6