Difference between revisions of "Simple maze"
Jump to navigation
Jump to search
(Move Visual Basic code to the end (alphabetical order)) |
|||
Line 220: | Line 220: | ||
######.###.#.#.###.#.###.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.###.######### | ######.###.#.#.###.#.###.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.###.######### | ||
##.......#.#...........#.#.....#.#.#.#.#.#.....###...#.###.......#...#...####### | ##.......#.#...........#.#.....#.#.#.#.#.#.....###...#.###.......#...#...####### | ||
</pre> | </pre> | ||
Line 632: | Line 443: | ||
##_______!_________!_____!_______!_!_________________!_____!___________!_____!_____!_______!_!_____!## | ##_______!_________!_____!_______!_!_________________!_____!___________!_____!_____!_______!_!_____!## | ||
###################################################################################################### | ###################################################################################################### | ||
</pre> | |||
== Maze Generator in [[Visual Basic]] 6 == | |||
<div style="background-color: #EEEEEE; border:dashed black 1px; padding:1em"> | |||
<syntaxhighlight lang="vb"> | |||
'''''''''''''''''''''''''' | |||
' Perfect Maze Generator ' | |||
' Icey ' | |||
' Oct 2006 ' | |||
' Public Domain ' | |||
'''''''''''''''''''''''''' | |||
' this code is designed to be run from a module, using sub main | |||
' all variables are declared | |||
Option Explicit | |||
' 0 is the most random, randomisation gets lower after that | |||
' less randomisation means more straight corridors | |||
Private Const RANDOMISATION As Integer = 5 | |||
' the spaces across - this must be an odd number | |||
Private Const MAZE_X As Integer = 53 | |||
' the spaces down - this must be an odd number | |||
Private Const MAZE_Y As Integer = 17 | |||
' used for storing the current square and squares potentially to move to | |||
Private Type COORDS | |||
X As Integer | |||
Y As Integer | |||
End Type | |||
' stores the directions that corridors go in | |||
Dim cDir(3) As COORDS | |||
' these can be any odd numbers | |||
Dim blnMaze(MAZE_X, MAZE_Y) As Boolean | |||
Private Sub GenerateMaze() | |||
Dim cN As COORDS, cS As COORDS | |||
Dim intDir As Integer, intDone As Integer | |||
Dim blnBlocked As Boolean | |||
Randomize | |||
Erase blnMaze | |||
Do | |||
' this code is used to make sure the numbers are odd | |||
cS.X = 2 + (Int(((MAZE_X - 1) * Rnd) / 2) * 2) | |||
cS.Y = 2 + (Int(((MAZE_Y - 1) * Rnd) / 2) * 2) | |||
' first one is free! | |||
If intDone = 0 Then blnMaze(cS.X, cS.Y) = True | |||
If blnMaze(cS.X, cS.Y) Then | |||
' always randomisation directions to start | |||
RandomDirections | |||
Do | |||
' only randomisation directions, based on the constant | |||
If Int(RANDOMISATION * Rnd) = 0 Then RandomDirections | |||
blnBlocked = True | |||
' loop through order of directions | |||
For intDir = 0 To 3 | |||
' work out where this direction is | |||
cN.X = cS.X + (cDir(intDir).X * 2) | |||
cN.Y = cS.Y + (cDir(intDir).Y * 2) | |||
' check if the tile can be used | |||
If IsFree(cN) Then | |||
' create a path | |||
blnMaze(cN.X, cN.Y) = True | |||
' and the square inbetween | |||
blnMaze(cS.X + cDir(intDir).X, cS.Y + cDir(intDir).Y) = True | |||
' this is now the current square | |||
cS.X = cN.X | |||
cS.Y = cN.Y | |||
blnBlocked = False | |||
' increment paths created | |||
intDone = intDone + 1 | |||
Exit For | |||
End If | |||
Next | |||
' loop until a path was created | |||
Loop Until blnBlocked | |||
End If | |||
' create enough paths to fill the whole grid | |||
Loop While intDone + 1 < ((MAZE_X - 1) * (MAZE_Y - 1)) / 4 | |||
End Sub | |||
' this changes the direction to go from the current square, to the next available | |||
Private Sub RandomDirections() | |||
' clear the array | |||
Erase cDir | |||
' four possible sets of directions | |||
Select Case Int(3 * Rnd) | |||
Case 0 | |||
cDir(0).X = -1: cDir(1).X = 1 | |||
cDir(2).Y = -1: cDir(3).Y = 1 | |||
Case 1 | |||
cDir(3).X = -1: cDir(2).X = 1 | |||
cDir(1).Y = -1: cDir(0).Y = 1 | |||
Case 2 | |||
cDir(2).X = -1: cDir(3).X = 1 | |||
cDir(0).Y = -1: cDir(1).Y = 1 | |||
Case 3 | |||
cDir(1).X = -1: cDir(0).X = 1 | |||
cDir(3).Y = -1: cDir(2).Y = 1 | |||
End Select | |||
End Sub | |||
' checks if a tile is free for use | |||
Private Function IsFree(cF As COORDS) As Boolean | |||
' check it's within the grid | |||
If cF.X < MAZE_X And cF.X > 1 And cF.Y < MAZE_Y And cF.Y > 1 Then | |||
' check it hasn't been used yet | |||
IsFree = (blnMaze(cF.X, cF.Y) = False) | |||
End If | |||
End Function | |||
' this code should be run from a module | |||
' go to Project > [projectname] Properties | |||
' and then select Sub Main from the Startup Object list | |||
Sub Main() | |||
' the maze is added to this string, which is then copied to the clipboard | |||
Dim strOutput As String | |||
GenerateMaze | |||
Dim A As Integer, B As Integer | |||
' loop through squares | |||
For A = 1 To MAZE_Y | |||
For B = 1 To MAZE_X | |||
' check if a path was created here | |||
If blnMaze(B, A) Then | |||
' empty | |||
strOutput = strOutput & " " | |||
Else | |||
' wall | |||
strOutput = strOutput & "#" | |||
End If | |||
Next | |||
' go down to the next row | |||
strOutput = strOutput & vbNewLine | |||
Next | |||
Clipboard.Clear | |||
Clipboard.SetText strOutput | |||
' tell the user what has happened | |||
MsgBox "Maze copied to the clipboard.", vbInformation, "Maze generator" | |||
End Sub | |||
</syntaxhighlight> | |||
</div> | |||
=== Examples === | |||
Randomisation: 0 | |||
<pre> | |||
########################################### | |||
# # # # # # | |||
# ### # ##### # # ##### ### ### # ### ##### | |||
# # # # # # # # # # # # # # | |||
# # # # # # # # ##### ##### # # # # ##### # | |||
# # # # # # # # # # # # # # | |||
# ##### # # # ### # ### ######### ##### # # | |||
# # # # # # # # # # # # # # # | |||
### ### # # ### # ### # # # # # ##### ### # | |||
# # # # # # # # # # # # # | |||
# # # ### # # # ### # # ### ########### ### | |||
# # # # # # # # # # # # # # | |||
# ######### # ######### # # # ### # # ### # | |||
# # # # # # # # # # # # # # | |||
# # # # # ### # # ### ### # ### # # ### # # | |||
# # # # # # # # # # # # # # # # # | |||
# # # # # # ##### # # # ### # ### # # ##### | |||
# # # # # # # # # # # # # # # # | |||
# # # ### # # # # # # ### # ### ##### # # # | |||
# # # # # # # # # # # # # | |||
# ####### # # # ######### ### ########### # | |||
# # # # # | |||
########################################### | |||
</pre> | |||
Randomisation: 5 | |||
<pre> | |||
##################################################### | |||
# # # # # # | |||
# ############### # # # # ##################### # # # | |||
# # # # # # # # # # # | |||
####### # # # # # # # # ######################### # # | |||
# # # # # # # # # # # # # # | |||
# # # # ### ##### # # # # # ################### # # # | |||
# # # # # # # # # # # # # # # # # # | |||
# # # # # ### # # # # # ### ######### # # # # ### # # | |||
# # # # # # # # # # # # # # # # # # # | |||
# # # # # ##### ##### # # # # ######### # # ### # # # | |||
# # # # # # # # # # # # # # # # # | |||
# # # # # # ########### # # ######### # # # # ### # # | |||
# # # # # # # # # # # # # # # # # # # # # | |||
# # # # # # # # # # # # # # # # # # # # # # ### # # # | |||
# # # # # # # # # # # # # # | |||
##################################################### | |||
</pre> | </pre> | ||
[[Category:Articles]] | [[Category:Articles]] |
Revision as of 21:48, 26 December 2014
Maze Generator in C++
Simple maze generator written in 10 minutes :) The source code is public domain.
// Simple Maze Generator in C++ by Jakub Debski '2006
#include <time.h>
#include <vector>
#include <list>
using namespace std;
int main()
{
srand(time(0));
const int maze_size_x=80;
const int maze_size_y=25;
vector < vector < bool > > maze;
list < pair < int, int> > drillers;
maze.resize(maze_size_y);
for (size_t y=0;y<maze_size_y;y++)
maze[y].resize(maze_size_x);
for (size_t x=0;x<maze_size_x;x++)
for (size_t y=0;y<maze_size_y;y++)
maze[y][x]=false;
drillers.push_back(make_pair(maze_size_x/2,maze_size_y/2));
while(drillers.size()>0)
{
list < pair < int, int> >::iterator m,_m,temp;
m=drillers.begin();
_m=drillers.end();
while (m!=_m)
{
bool remove_driller=false;
switch(rand()%4)
{
case 0:
(*m).second-=2;
if ((*m).second<0 || maze[(*m).second][(*m).first])
{
remove_driller=true;
break;
}
maze[(*m).second+1][(*m).first]=true;
break;
case 1:
(*m).second+=2;
if ((*m).second>=maze_size_y || maze[(*m).second][(*m).first])
{
remove_driller=true;
break;
}
maze[(*m).second-1][(*m).first]=true;
break;
case 2:
(*m).first-=2;
if ((*m).first<0 || maze[(*m).second][(*m).first])
{
remove_driller=true;
break;
}
maze[(*m).second][(*m).first+1]=true;
break;
case 3:
(*m).first+=2;
if ((*m).first>=maze_size_x || maze[(*m).second][(*m).first])
{
remove_driller=true;
break;
}
maze[(*m).second][(*m).first-1]=true;
break;
}
if (remove_driller)
m = drillers.erase(m);
else
{
drillers.push_back(make_pair((*m).first,(*m).second));
// uncomment the line below to make the maze easier
// if (rand()%2)
drillers.push_back(make_pair((*m).first,(*m).second));
maze[(*m).second][(*m).first]=true;
++m;
}
}
}
// Done
for (size_t y=0;y<maze_size_y;y++)
for (size_t x=0;x<maze_size_x;x++)
{
if (maze[y][x]==true)
printf(".");
else
printf("#");
}
return 0;
}
Examples
######.........#.#.......#.....#...#.....#.........#.#...#.#.......#.......##### ######.#.###.#.#.#.#######.#.#####.#.###.#.#.#####.#.###.#.#.#######.########### .....#.#.#...#.#.........#.#.#.....#.###...#.#.....#.......#.......#.....####### .#.#.###.#.#####.#.#.#######.#.#.#.#.#####################.#.###.#######.####### .#.#.#...#...#...#.#...#.#.#.#.#.#.#.........#.....#...........#.#.............# ####.#.#######.#######.#.#.#.#.#.#######.#.#.#.#.#.#.#######.#######.#######.#.# ##...#...#####.#.#####.#...#...#.#...#.#.#.#...#.#...###...#.#.......#.......#.# ####.###.#####.#.#####.#.###.#.###.###.#.#.###.#########.#####.###.############# .........###.#.....###.#...#.#.#.#.......#.#...#...#.#.#.#.......#.###...#.....# ########.###.#.#.#.###.#.#.###.#.#.#####.#.###.#.###.#.#.#.#.###.#####.###.#.### .......#.....#.#.#.#...#.#...........#...#.#.....#.......#.#...#.#.........#...# ####.#.#.#####.#.###.#######.#######.###.#.#.###.#.#####.#.#####.#.#.#####.##### ...#.#.#.......#...#.....#.....#.#...#####.#...#.......#.#...#.....#...#.#.....# ##.###.#.#.#.###.#####.#.#####.#.#.#######.#####.#####.#.###.#.###.#####.#####.# ##...#...#.#.#.......#.#.....#...#.......#...#...#.....#.....#...#...........#.# ####.#.###########.###.#.###.#####.#######.###.###########.###.###.#####.###.### ####...###.....#...#.#.#...#...........###...#.###...#.###.###...#.....#.#.....# ####.#####.#######.#.###.###.#.#####.#.#############.#.###.#####.#####.#.###.### ####.........#.#...#.....#.#.#.#.....#.###.#...#.............#...#####.#...#...# ######.#.#####.#.###.#.#.#.###.#######.###.#.#####.###.#################.####### ######.#...#.#.....#.#.#.#...#...###...###.....#...#.......#########...#.......# ######.###.#.#####.#####.#.###.#.###.#.###.#.###.###.#####.#########.#########.# ######.#.#.#...###...#...#.#.#.#...#.#.....#.#.#...#.###...#########...#.......# ########.#.###.#######.#.#.#.###.#######.###.#.#####.###############.#.###.##### ########...###.........#.#.......#######.#.....#####.......#########.#.........#
With little changes you can get cool results, f.e.
else
{
// drillers.push_back(make_pair((*m).first,(*m).second));
// drillers.push_back(make_pair((*m).first,(*m).second));
// change to
for (size_t index=0;index<10;index++)
drillers.push_front(make_pair((*m).first,(*m).second));
gives "star-like" effect:
.#.#...#...#.....#...#...#...#.#...#...#.....#...#...#.......#...#.....#.....#.# .#.###.###.#####.###.###.###.#.###.###.#.#####.###.###.#######.###.#####.#####.# ...#.#...#...#...#.#...#...#...#.#...#.....#...#.......#.............#.#...#...# ##.#.###.###.###.#.###.###.###.#.###.#.#####.###.#######.#############.#.###.### .......#...#.#.#.....#.#.#.......#.#.....#...#...#.#...#...#...#.#.#.#...#...#.# ######.###.#.#.#####.#.#.#######.#.###.###.###.###.#.###.###.###.#.#.#.###.###.# ...#.#...#...#...#.......#.#...#.....#.....#...#.....#...#...#.#.......#...#...# ##.#.###.###.###.#######.#.###.#####.#.#####.###.#####.###.###.#.#######.###.### .#...#.#.#.#...#.#.#.....#.#.#...#.......#...#.#...#.#.#...#.#...#.#...#.#...#.# .###.#.#.#.###.#.#.#####.#.#.###.#####.###.###.#.###.#.#.###.#.###.#.###.#.###.# .................#...#...#.#.#.#...#...#.......................................# ####.###.###.###.###.###.#.#.#.###.###.#.###.###.###.###.###.###.###.###.###.### .#.#.#.#.#.#.#...........................#.#.#.#.#.#.#.#.#.#.#.#...#.#.#.#.#.#.# .#.###.###.#####.#.#.#####.#####.#.###.#.#.###.###.###.###.###.#######.###.###.# .................#.#.#.....#.....#.#...#.......................................# ##.###.#.###.#.###.#####.###.#.#.#####.###.#.#.###.#.###.###.#.#.###.#.###.#.#.# ...#...#.#...#.#...#.....#...#.#.#.......#.#.#...#.#...#...#.#.#...#.#...#.#.#.# .###.#.###.#.###.#.#######.#.#.#####.#.#####.###.###.#.#######.###.###.#.###.### .#...#.#...#.#...#.#.......#.#.#.....#.....#...#...#.#.......#...#...#.#...#...# ##.#.#####.###.#.###.###.###.#####.###.#.#.###.###.###.#.###.###.#.#####.#####.# ...#.#.....#...#.#...#...#...#.....#...#.#...#...#...#.#...#...#.#.....#.....#.# .#.###.#.#####.###.###.###.###.#.###.#.###.#.###.###.###.#####.###.###.###.#.### .#.#...#.#.....#...#...#...#...#.#...#...#.#...#...#...#.....#...#...#...#.#...# .#####.#####.###.###.###.###.#.###.###.#####.#.###.###.###.#.###.#.#.###.###.### .#.....#.....#...#...#...#...#.#...#.......#.#...#...#...#.#...#.#.#...#...#...#
or
(*m).second-=2;
// if ((*m).second<0 || maze[(*m).second][(*m).first])
// change to
if ((*m).second<0 || (maze[(*m).second][(*m).first] && rand()%5))
allows loops (sample loop top left corner is marked with comas):
.......#,,,,,,,,.#####.....#####...#...............#...#.###.....###...#.#.#.### .#######,#####.#,#######.#######.#.#############.#.###.#.###.#########.#.#.#.### .#...#..,,,,,#.#,,,###...#######.#.#...#.........#.....#.......................# .#.###.#####,#####,###.#.#########.#.#########.#####.#.#.###.#.#########.#.#.#.# .#.....#....,,,,,,,....#.#######.....#...#...#...###.#.......#.###.#.....#.#...# .#.#.#####.#.#.###.#################.#.#.###.#######.#####.###.###.#.#####.##### .#...#.....#.....#.#...#.......#.#...#.#.....#######...#...#...#.#.#.###...#.### .#.###.###.#.###.#.###.#.#######.#.#.###.#.#.#######.###########.#.#######.#.### ...#...#.#.#.#...#.....#.....#...#.#.....#...#.#####.......#.....#.........#...# ####.#.#.#.#####.#.#.#.###.#.###.#######.#.#.#.#######.#.#.#.#.#.###.#######.### ...#.#.#.....#.....#.#.#...#.#...#.....#.#.#...#...#...#.#...#.#...............# .###.###.#####.#######.###.#.###.#.###.###.#.#.#.#####.#######.###.#######.#.#.# .....#.#.#...#...#...#.#...#...........#.....#.........#.#####.#...#...###...#.# ##.###.#.#.#.#.#.#.#########.#.###.###.#.###.#######.###.#####.###.#.#.###.##### ...#.......#...#...#.......#.#.#...#...#...#.#.#...#.#.....#...#...#.#.#...#...# ####.#.#######.#.#.#.###.###.#.#.#####.#####.#.#.#####.#.#.#.#.#######.#####.### .......#...#...#.#.....#.#...#...#...............#.....#.#...#...........#...### ##.#####.###########.#####.#########.#.###.###.#.#########.###.###.#.#.###.#.### .......#...#.#.......#.....#.....#...#.#.....#.#.#...........#...#.....#.#.#...# ##.#.###.###.#.#.###.#######.#.#.#####.###.#####.###.#.#.#####.###.#.###.###.### ##.#...#.......#...#.........#.#.......#...###.#.....#...#####...#.............# ########.###.#.#.#########.#####.#.#####.#####.#.#####.#.#####.#####.#.#.####### ##.........#.#...#.#...#...#...#.....#.....#...#.....#.#.#####.....#...#.....### ######.###.#.#.###.#.###.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.###.######### ##.......#.#...........#.#.....#.#.#.#.#.#.....###...#.###.......#...#...#######
Maze Generator in Javascript
The following code is based on the perl implementation:
#!/usr/bin/env node.exe
(function () {
var DIRECTIONS = {
'N' : { dy: -1, opposite: 'S' },
'S' : { dy: 1, opposite: 'N' },
'E' : { dx: 1, opposite: 'W' },
'W' : { dx: -1, opposite: 'E' }
};
var WIDTH = 60,
HEIGHT = 30,
map = [];
var prefill = function () {
for (var x = 0; x < WIDTH; x++) {
map[x] = [];
for (var y = 0; y < HEIGHT; y++) {
map[x][y] = {};
}
}
};
var shuffle = function (o) {
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
var carve = function (x0, y0, direction) {
//console.log('[%d, %d, "%s"]', x0, y0, direction);
var x1 = x0 + (DIRECTIONS[direction].dx || 0),
y1 = y0 + (DIRECTIONS[direction].dy || 0);
if (x1 == 0 || x1 == WIDTH || y1 == 0 || y1 == HEIGHT) {
return;
}
if ( map[x1][y1].seen ) {
return;
}
map[x0][y0][ direction ] = true;
map[x1][y1][ DIRECTIONS[direction].opposite ] = true;
map[x1][y1].seen = true;
var directions = shuffle([ 'N', 'S', 'E', 'W' ]);
for (var i = 0; i < directions.length; i++) {
carve(x1, y1, directions[i]);
}
};
var output = function () {
var output = '';
for (var y = 0; y < HEIGHT; y++) {
for (var x = 0; x < WIDTH; x++) {
output += ( map[x][y].S ? ' ' : '_' );
output += ( map[x][y].E ? ' ' : '!' );
}
output += '\n';
}
output = output.replace(/_ /g, '__');
console.log(output);
};
prefill();
carve(WIDTH/2, HEIGHT/2, 'N');
output();
})();
Examples
$ ./fixed.js _!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_! _! ______ !__ ! ____ _________! ! __ !__ ! ! ! ____ _! __________ ! !__________ ____ ! ! __ ! _! ! ! _! _! ! !__________ ! !___! ! !__ !___! ! !___!__ ! _! _! ! __ ! _!________ ! _!_! ! ! ! ! ! !__ ! _! !_! !____ ! _! ! !__ __ ! ! _! _! !__ ! _! ! ! _!__ ! ! _! !___!__ ! ______ ! !_______! ! !_!___! ! ! _! !_______! ! _!__ ! !__ ! !_! ! _!___! ___!_____! ! ! ! ___!___! !____ !_!__ ! _! !___________!______ ! ! !_! _!_!__ ! ! _!__ ! _!__ ! !_____! ! __ !____ ! __ ! !___! ! _______! ! ! ! _____! _! !________ __ ! !_! ! _! ! ! ! !_______! ! ___!____ ! !___! ! ! ! _! ! ! ! ! !____ ! ___! !_!__ ! ! _!__ ! ! ____ ! !___!__ !_! ! _! !___! !__ ___! _! ! ! ! _________! ! !__ !_! !___! ! ! ! __ !__ ! ! ! !___!_!__ ! ! ! !__ ! !______ !____ ! _! ! ! ! ! ! ! ! ! ! ! _! ! ! _! !_____! !_! ! ! !___! _! _! !________ !_! ! !___! _!______ ! ! ! _! _! !__ ! ! !___! !___! !___! !___! ! ! ! !______ _! ! _!__ ! !__ ! !__ ! ! !_____!__ ! _! ____ ! !_! ! ! ! _! ! ! ! !___! _!__ _! ! ___! _!___! ! !____ ! ! _!____ ! ! !__ ! !_____! !___!__ ____ _!__ ___! _!__ ! ! ! ! _! ! !___! ! !__ ! _! ! !______ _____!____ ! ! !_________! !__ ! !______ !__ ! ! _! _! ! !_! ! _!__ !_! ! _! !_______! !__ ! _! ! ! !______ ! ! __ ! _! !______ ! ___! _!_________! ___! ! _____! !_____! !_!______ ! _! _!__ !__ ___! ! !_____! !____ _! !_!_____!__ ! !__ !_____! _! ! ! _____! ! _!____ ! ! !____ ! ! ____ !_!__ ! _! !_____! ! ___! _____! _! ! _! ! __ !___!_____! ! ! ! !___!____ !__ ! ! ! ! ! !____ ! ! !____ !_______! _!__ ! ! ! ! ! ___! ___! ! _! !__ !__________ !__ _! ! !________ !_____! ! !___!_________!__ !_______!____ ! _! !___!_! ! !___! _____! !___! _! _! !__ ! _! ! ! _!_________!__ ! ___!____ ! ___________! __ _______! ! _! !_! _____!__ !____ ! _!__ ! ! ! _!__ ! ! ! !__ _! !__ ______ ! _!____ ! _! !__ ! __ !___! _! ! ___! _! ___! ____ !_! ! ! _! ! !__ !___! _!___!_!__ !__ !__ !__ !__ ! ! ! __ !___! _! _!_! _!_______!___! !__ ! ! _!____ ! !__ !__ ! ! _! ___! !__ !____ !__________ !__ !___!_____! ! ! ___! ! ___! _! ___!__ ______ ____ ! ! ! _!__ ! !__ ! ! ! ! ! ! ! !__ !____ !__ ! ! _______!________ ___!_! !_! ! !__ ___! _! __ !______ ! ! ! ! ! ! _! _!__ ! !_! !___! ! !___! _! ! ! !_____! ! ! ______ !__ ! ___! _! !__ !____ ! ! ___!______ ! !___! ! !__ ! _! ! ___! ! ! ___! ! ! ! _! !___! __ ! !___! ! ! ! _! _!__ ! _! ! ! _! ! ! _! ! __ ! _!__ ! _!_! _! _! ! ! _! ! ! ! ! ! !___! !_________! _!__ ! _! ! !_! ! ____ ! !__ ! !___! _!_! !_____! !_____! ___! ! _! ! _! _! !__ ! !_! ! _!___! ! ! ! _!____ !_!__ ! ! ___!_! ___!_____! ! ! !______ !____ ! _! !_! ! ! ! _!__ ! ! _!__ _!_! __ ! ! !_! ! _!__ ___! ! _! ! _______! __ ! _!__ !_! ! _! !_______!__ ! !____ ! ! ! ! _! _! !____ !_______! !___!_____! ! _!__ ! ___!_! _!_! _______! ! _! ! ! ! _!_____!__________ ! !____ ! !___! ! _! !__ ! !__ ! ____ ___! _____! ! __ ! ! ! _! ___! ! _! !__ ! ! ! !_!____ ! ____ ! ! __ ! ! _! ! ! ! ! _!__ !_! !_____! ! !_! ___! ! ! !___!__ ! !_! _! ___! !__ ! !_____! !__ ! ___!____ ! ! !__ !_! !__ ! !_! ! ! ! _!_______!_________!___________!___!_!_________!_________!_________!___________!_____________!_____!_________!_____!___!
Maze Generator in Perl
This is a complete recursive backtracking maze generator in Perl:
#!/usr/bin/env perl
use strict;
use warnings;
no warnings 'recursion';
no warnings 'uninitialized';
use List::Util qw/shuffle/;
### Constants
my ( $WIDTH, $HEIGHT ) = ( 50, 30 );
my %DIRECTION = (
N => { dy => -1, opposite => 'S' },
S => { dy => 1, opposite => 'N' },
E => { dx => 1, opposite => 'W' },
W => { dx => -1, opposite => 'E' },
);
### Code
my $map = carve( [], $WIDTH / 2, $HEIGHT / 2, 'E' );
print output($map);
sub carve {
my ( $map, $x0, $y0, $direction ) = @_;
my $x1 = $x0 + $DIRECTION{$direction}{dx};
my $y1 = $y0 + $DIRECTION{$direction}{dy};
return if $x1 == 0 or $x1 == $WIDTH or $y1 == 0 or $y1 == $HEIGHT;
return if defined $map->[$x1][$y1];
$map->[$x0][$y0]{$direction} = 1;
$map->[$x1][$y1]{ $DIRECTION{$direction}{opposite} } = 1;
carve( $map, $x1, $y1, $_ ) for shuffle keys %DIRECTION;
return $map;
}
sub output {
my ($map) = @_;
my $output = '';
for my $y ( 0 .. $HEIGHT ) {
for my $x ( 0 .. $WIDTH ) {
if ( defined $map->[$x][$y] ) {
$output .= $map->[$x][$y]{S} ? ' ' : '_';
$output .= $map->[$x][$y]{E} ? ' ' : '!';
}
else {
$output .= '##';
}
}
$output .= "\n";
}
$output =~ s/_ /__/gs;
return $output;
}
Example
$ perl-generator.pl ###################################################################################################### ## ______ ! ________ ! __ ! __ ! __ ! ! __ ! ___! _! __ ! ____ ! ! __ ! !## ##______ ! !___! ______ !___!___! !__ ! ! ! ! _! ! _! !_______!_____! ! !____ ! !___! !_! ! ___!## ## _! ! !______ ! !________ !__ !_! ! ! !__ ! ! _! !__ ______ ! _!__ _! ! !_________!_! !## ## ! ! _! ! !___! !__ ! _! _! ! _! !__ !_! ! ! _____! __ ! ! __ ! ! _! ! ______ ! _! !## ## !_____!__ ! ! ___! _! ! ___!_!__ ___!__ ! !_!__ ! ! ! ! !___! ! !__ ! !__ !__ !_____! !## ##_! ____ ! ! !__ ! !__ ! ! ! ! ____ ! ! _____! ! ___! ! ! ! ! !______ ! _! !_____! ! ! ___!## ## _!__ ! !_! _!____ ! ! ! ! !__ ! !___!______ !__ ! ___! !_! !____ ! ! !_____! __ ! !___!____ !## ## __ !______ ! _____! !_!_____!______ !__ _!__ ! ! ! ! ! _! !__ ! !__ ___! _!__ ! __ ! !## ##___!__ ! ___! ! ! ___! ________ _!__ ! ! ! ! ! ! ! ! ! ___!__ ! ! ! _! !____ ! ! !____ !## ## ! _!____ !__ !__ ! _!______ !_______! ! !__ !_! !_! ! !__ ! ! _!_! ! ! _!____ !__ ! ! ! !## ## ! ! ! ! ___!__ ! !____ ! !__ ! __ ! !___! _! _! ! !__ ! ! ! ! !__ ! ! ___! !___! ! !## ## ! ! ! ! ! _! ___! __ !___! ! _! ! _! !____ ! !____ ! !_____!___!_____! _! !____ ! ! ! _! !## ## !___!_!__ ! _! !__ ! !__ ! !_____! ! ! ! ! ! ! ___!____ ! __ !__ ! ! __ !___! ! !__ !## ## ! ____ !_!__ !_! _! ! ! !______ ! !___! ! !_____! ____ ! !___! _! _! !_! !__ ___!__ !_!## ## ! ! !____ !__ ! ! _!___!_____! _! ! ___! !__ ! _! _! !_____! ! ! !__ !_! ! ! ! __ !__ !## ## !___! ! !_____! !____ ! _______! ! _!__ ! ! _!__ !__ !_________! _!__ ! ! _!__ !__ !____ !## ## ! ___! ! _! __ __ !___! ! __ ! ! _! ! ! ___! ! !____ ! !__ !___! ! !__ !____ ! !## ## !__ ! ! ! ! _! !__ !_____! !_____!_____! ! !___! _!___! ! ___!________ _! !__ !___! _! !## ## _! ! _!___!____ !____ ! ___! __ ! ___! !__ ! _!__ ! _!______________ ! _! !_______! ! !## ## ___! !__ ____ ! __ ! ! ! ___! _!__ ! !__ !_! ! !_! ! ! ! ____ !_! ! __ ! __ _! !## ## ! !__ ! ! ! ! ! ! !___! ! _!____ !__ ! ! ! _! ! ! _! ! ! ! ! ! ! !_____! ! ! ! ! _! _!## ## !_!____ ! ! !___! _!__ ! ! ___! ! !__ ! ! ! _!___! _! ! !___!_! ! !__ _!__ ! ! !__ !__ !## ##______ !___!____ ! ! _!_! ! !_______!____ ! ! !____ ! ! !___!____ ! !__ ! ! ___! ! ! !__ ! !## ## ___!____ !____ !_! ! ! ___!____________ ! !___! ___! _! ! ! !___! _! _! __ !____ !___!## ## ! ! ___! ! ___!_! ! ________ ! ___!_! ___!__ ! ! _!___! !_! ___!___! _! _____! !__ !## ## _!___! ___! !_! _____! !__ _! _! ! __ _! ! ! !__ ! ! ! _!__ _____! ___! !__ ! !## ##_________! ___! _! _!__ !__ !__ ! !___! ! _! !___!_____! !_!___! ___!__ _____! _!__ !__ !## ## ______ ! !____ ! ! !__ ! _! ! _!_______! ! !__ ! __ _! ______ ! __ !_! ! _! ! _! !## ##_______!_________!_____!_______!_!_________________!_____!___________!_____!_____!_______!_!_____!## ######################################################################################################
Maze Generator in Visual Basic 6
''''''''''''''''''''''''''
' Perfect Maze Generator '
' Icey '
' Oct 2006 '
' Public Domain '
''''''''''''''''''''''''''
' this code is designed to be run from a module, using sub main
' all variables are declared
Option Explicit
' 0 is the most random, randomisation gets lower after that
' less randomisation means more straight corridors
Private Const RANDOMISATION As Integer = 5
' the spaces across - this must be an odd number
Private Const MAZE_X As Integer = 53
' the spaces down - this must be an odd number
Private Const MAZE_Y As Integer = 17
' used for storing the current square and squares potentially to move to
Private Type COORDS
X As Integer
Y As Integer
End Type
' stores the directions that corridors go in
Dim cDir(3) As COORDS
' these can be any odd numbers
Dim blnMaze(MAZE_X, MAZE_Y) As Boolean
Private Sub GenerateMaze()
Dim cN As COORDS, cS As COORDS
Dim intDir As Integer, intDone As Integer
Dim blnBlocked As Boolean
Randomize
Erase blnMaze
Do
' this code is used to make sure the numbers are odd
cS.X = 2 + (Int(((MAZE_X - 1) * Rnd) / 2) * 2)
cS.Y = 2 + (Int(((MAZE_Y - 1) * Rnd) / 2) * 2)
' first one is free!
If intDone = 0 Then blnMaze(cS.X, cS.Y) = True
If blnMaze(cS.X, cS.Y) Then
' always randomisation directions to start
RandomDirections
Do
' only randomisation directions, based on the constant
If Int(RANDOMISATION * Rnd) = 0 Then RandomDirections
blnBlocked = True
' loop through order of directions
For intDir = 0 To 3
' work out where this direction is
cN.X = cS.X + (cDir(intDir).X * 2)
cN.Y = cS.Y + (cDir(intDir).Y * 2)
' check if the tile can be used
If IsFree(cN) Then
' create a path
blnMaze(cN.X, cN.Y) = True
' and the square inbetween
blnMaze(cS.X + cDir(intDir).X, cS.Y + cDir(intDir).Y) = True
' this is now the current square
cS.X = cN.X
cS.Y = cN.Y
blnBlocked = False
' increment paths created
intDone = intDone + 1
Exit For
End If
Next
' loop until a path was created
Loop Until blnBlocked
End If
' create enough paths to fill the whole grid
Loop While intDone + 1 < ((MAZE_X - 1) * (MAZE_Y - 1)) / 4
End Sub
' this changes the direction to go from the current square, to the next available
Private Sub RandomDirections()
' clear the array
Erase cDir
' four possible sets of directions
Select Case Int(3 * Rnd)
Case 0
cDir(0).X = -1: cDir(1).X = 1
cDir(2).Y = -1: cDir(3).Y = 1
Case 1
cDir(3).X = -1: cDir(2).X = 1
cDir(1).Y = -1: cDir(0).Y = 1
Case 2
cDir(2).X = -1: cDir(3).X = 1
cDir(0).Y = -1: cDir(1).Y = 1
Case 3
cDir(1).X = -1: cDir(0).X = 1
cDir(3).Y = -1: cDir(2).Y = 1
End Select
End Sub
' checks if a tile is free for use
Private Function IsFree(cF As COORDS) As Boolean
' check it's within the grid
If cF.X < MAZE_X And cF.X > 1 And cF.Y < MAZE_Y And cF.Y > 1 Then
' check it hasn't been used yet
IsFree = (blnMaze(cF.X, cF.Y) = False)
End If
End Function
' this code should be run from a module
' go to Project > [projectname] Properties
' and then select Sub Main from the Startup Object list
Sub Main()
' the maze is added to this string, which is then copied to the clipboard
Dim strOutput As String
GenerateMaze
Dim A As Integer, B As Integer
' loop through squares
For A = 1 To MAZE_Y
For B = 1 To MAZE_X
' check if a path was created here
If blnMaze(B, A) Then
' empty
strOutput = strOutput & " "
Else
' wall
strOutput = strOutput & "#"
End If
Next
' go down to the next row
strOutput = strOutput & vbNewLine
Next
Clipboard.Clear
Clipboard.SetText strOutput
' tell the user what has happened
MsgBox "Maze copied to the clipboard.", vbInformation, "Maze generator"
End Sub
Examples
Randomisation: 0
########################################### # # # # # # # ### # ##### # # ##### ### ### # ### ##### # # # # # # # # # # # # # # # # # # # # # # ##### ##### # # # # ##### # # # # # # # # # # # # # # # # ##### # # # ### # ### ######### ##### # # # # # # # # # # # # # # # # # ### ### # # ### # ### # # # # # ##### ### # # # # # # # # # # # # # # # # # ### # # # ### # # ### ########### ### # # # # # # # # # # # # # # # ######### # ######### # # # ### # # ### # # # # # # # # # # # # # # # # # # # # ### # # ### ### # ### # # ### # # # # # # # # # # # # # # # # # # # # # # # # # ##### # # # ### # ### # # ##### # # # # # # # # # # # # # # # # # # # ### # # # # # # ### # ### ##### # # # # # # # # # # # # # # # # # ####### # # # ######### ### ########### # # # # # # ###########################################
Randomisation: 5
##################################################### # # # # # # # ############### # # # # ##################### # # # # # # # # # # # # # # ####### # # # # # # # # ######################### # # # # # # # # # # # # # # # # # # # # ### ##### # # # # # ################### # # # # # # # # # # # # # # # # # # # # # # # # # # ### # # # # # ### ######### # # # # ### # # # # # # # # # # # # # # # # # # # # # # # # # # ##### ##### # # # # ######### # # ### # # # # # # # # # # # # # # # # # # # # # # # # # # ########### # # ######### # # # # ### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # #####################################################