Xref: utzoo comp.sources.wanted:14502 alt.sources.d:1170 rec.games.misc:12829 rec.games.programmer:2689 Path: utzoo!utgpu!cs.utexas.edu!sdd.hp.com!news.cs.indiana.edu!iuvax!bronze.ucs.indiana.edu!mdchaney From: mdchaney@bronze.ucs.indiana.edu (M Darrin Chaney) Newsgroups: comp.sources.wanted,alt.sources.d,rec.games.misc,rec.games.programmer Subject: Re: Maze generation Keywords: how-to maze generate program wanted Message-ID: <78217@iuvax.cs.indiana.edu> Date: 14 Dec 90 16:34:58 GMT References: <1215@syacus.acus.oz> Sender: news@iuvax.cs.indiana.edu Organization: Indiana University, Bloomington Lines: 226 In article <1215@syacus.acus.oz> martins@syacus.acus.oz (Martin Schwenke) writes: >I am interested in software or algorithms for generating mazes with >unique solutions. I am also, but less, interested in maze solving >algorithms, and programs. > >Any useful info would be appreciated. Martin (and other gamers)- I have included at the bottom of this message a small recursive program/routine that will generate random mazes. It should run on an Ultrix/Unix platform with no modifications, or on a VMS platform with the "random/srandom" functions renamed to "rand/srand" (or, better yet, write the functions for VMS to use the built-in mth$random). Here is how it works. The maze is stored as a large array, in this case 500x500. You enter the maze size with command line options. Each piece of the array represents a cell. Each cell has four walls, numbered clockwise from 0 to 3. The wall is represented by its corresponding bit. If the bit is on, then the wall exists. Otherwise, the wall doesn't exist, and one can travel in that direction to the next cell. Keep in mind, then, that an unoccupied cell has a value of 15 decimal, or 1111 binary. To generate the maze, we must think recursively. First, we start at the upper left-hand corner (1,1). We'll call our maze generating function make_maze, and it will be called with 2 arguments, which are an x,y coordinate pair. So, to start the maze, we'll use make_maze(1,1). The first thing the function does is to pick a random permutation. For the four directions, taken one at a time, there are 4*3*2*1, 24, ways that they could be taken. So, we pick a number from 0 to 23. Then, we go through each of the four ways in that order. At each one, we test whether or not we can go that direction. If so, we call make_maze with that coordinate pair. If not, we simply try the next direction. The maze generating loop is only 16 lines. I included another piece of code that picks a suitable exit. As a matter of fact, the exit it picks is the edge cell that is farthest from the beginning (through the maze, that is). The version at the bottom will display its maze with the VT100 graphics set, which is available on almost all emulators. The picture isn't perfect, as I needed 4 little pieces that weren't there, but I think you'll get the picture. If you'd like, I also have a ReGIS version which draws the maze, then solves it, all graphically, and slow enough to watch how it works. I can make no guarantees that it works perfectly on a VT240, but it should for mazes down to 50x30 or so. If you'd like that version, just drop some email. If you have any questions, just write. Cheers- Darrin M Darrin Chaney mdchaney@bronze.ucs.indiana.edu mdchaney@rose.ucs.indiana.edu mdchaney@iubacs ------------------------------------------------------------------------------- /* M Darrin Chaney Command line options: -x : set nummber of columns -y : set number of rows -r : specify seed for random number generator make_maze -x 20 -y 20 -r 4 */ #include #include #include #define MAXX 500 #define MAXY 500 int deltax[4]={0,1,0,-1}; int deltay[4]={-1,0,1,0}; unsigned char maze[MAXX+1][MAXY+1]; int perms[24][4]={{0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1}, {1,0,2,3},{1,0,3,2},{1,2,0,3},{1,2,3,0},{1,3,0,2},{1,3,2,0}, {2,0,1,3},{2,0,3,1},{2,1,0,3},{2,1,3,0},{2,3,0,1},{2,3,1,0}, {3,0,1,2},{3,0,2,1},{3,1,0,2},{3,1,2,0},{3,2,0,1},{3,2,1,0}}; /* pieces array is just for the VT100 graphics viewer */ char pieces[16]={32,32,32,109,32,120,108,116, 32,106,113,118,107,117,119,110}; int maxx=21,maxy=21; int max_level=0,max_level_x,max_level_y; int srandom(); int random(); main(argc,argv) int argc; char *argv[]; { int i,j,k,x,y; char line[202]; int ran,gran=0,dir; for (i=1 ; imax_level) && ((x==1) || (y==1) || (x==maxx-1) || (y==maxy-1))) { max_level=level; max_level_x=x; max_level_y=y; } perm_num = random() % 24; for (k=0 ; k<4 ; k++) { direction=perms[perm_num][k]; i=x+deltax[direction]; j=y+deltay[direction]; if (maze[i][j]==15) { maze[x][y] -= (1 << direction); maze[i][j] -= (1 << (direction ^ 2)); make_maze(i,j,level+1,direction); } } } fatal_error(str) char *str; { fprintf(stderr,"Error: %s\n",str); exit(0); } ------------------------------------------------------------------------------- mdchaney@iubacs mdchaney@bronze.ucs.indiana.edu mdchaney@rose.ucs.indiana.edu