This is maze.c in view mode; [Download] [Up]
/* maze.c Future maze program. Right now it just generates mazes and prints them on VT100 screens in graphics mode. */ #include <ansi.h> #include <sgtty.h> #define USED 1 #define BOTTOM 2 #define RIGHT 4 #define repeat for (;;) #define cputs(s) fputs(s,stdout) #define movmem(a,b,c) memmove(b,a,c) #define fill(a,b,c) memset(a,c,b) int farx,fary,fardist; char *mazep; int w,h; #define maze(x,y) mazep[(w+1)*(y)+(x)] main(int argc,char **argv) { int x,y,n,d,m,straight,sinit; struct winsize ws; sinit = 3; if (argc>1) { sinit = atoi(argv[1]); if (!sinit) { puts("maze <x>\n" "<x> = \"straightness\" parameter (optional, default=3)"); exit(1); } } ioctl(0,TIOCGWINSZ,&ws); if (!ws.ws_row) ws.ws_row = 24; if (!ws.ws_col) ws.ws_col = 80; w = ws.ws_col/2-1; h = ws.ws_row-2; randomize(); mazep = (void *)sbrk((w+1)*(h+1)); if (!mazep) {puts("Out of memory!"); exit(1);} fill(mazep,(w+1)*(h+1),BOTTOM+RIGHT); for (x=1; x<=w; x++) maze(x,0) = BOTTOM; for (y=1; y<=h; y++) maze(0,y) = RIGHT; maze(0,0) = 0; x = y = 1; straight = d = 0; /* cputs("\033[H\033[2J"); drawmaze(); */ for (n=w*h; maze(x,y) |= USED,--n>0;) { /* cputs("\033[H"); drawmaze(mazep,w,h); */ NP: if (--straight<=0) {if (random(2)) d++; else d--; straight = sinit;} for (m=4; m>0; m--) { switch(d&3) { case 0: /* left */ if (x>1 && !(maze(x-1,y)&USED)) {maze(--x,y) &= ~RIGHT; goto CONTINUE1;} break; case 1: /* up */ if (y>1 && !(maze(x,y-1)&USED)) {maze(x,--y) &= ~BOTTOM; goto CONTINUE1;} break; case 2: /* right */ if (x<w && !(maze(x+1,y)&USED)) {maze(x++,y) &= ~RIGHT; goto CONTINUE1;} break; case 3: /* down */ if (y<h && !(maze(x,y+1)&USED)) {maze(x,y++) &= ~BOTTOM; goto CONTINUE1;} break; } d++; /* straight = sinit; */ } x = random(w)+1; /* seed a new path */ y = random(h)+1; repeat { if (maze(x,y)&USED && (x>1 && !(maze(x-1,y)&USED) || y>1 && !(maze(x,y-1)&USED) || x<w && !(maze(x+1,y)&USED) || y<h && !(maze(x,y+1)&USED))) break; x++; if (x>w) {x=1; y++; if (y>h) y=1;} } straight = 0; goto NP; CONTINUE1:; } findfar(1,1); x = farx; y = fary; findfar(x,y); if (y<=1) maze(x,0) &= ~BOTTOM; else if (x<=1) maze(0,y) &= ~RIGHT; else if (x>=w) maze(w,y) &= ~RIGHT; else maze(x,h) &= ~BOTTOM; x = farx; y = fary; if (y<=1) maze(x,0) &= ~BOTTOM; else if (x<=1) maze(0,y) &= ~RIGHT; else if (x>=w) maze(w,y) &= ~RIGHT; else maze(x,h) &= ~BOTTOM; drawmaze(); } drawmaze() { int x,y,n; static char table[] = " qjjqqmvkkxulwtn"; cputs("\033(0"); for (y=0; y<=h; y++) { for (x=0; x<=w; x++) { n = maze(x,y); if (x<w && maze(x+1,y)&BOTTOM) n+=BOTTOM*4; if (y<h && maze(x,y+1)&RIGHT) n+=RIGHT*4; if (x) putchar(n&BOTTOM ? table[5] : ' '); putchar(table[n>>1]); } putchar('\n'); } cputs("\033(B"); } /* recursive and stack-intensive distance finder: */ ifindfar(x,y,d,r) { /* d is "backwards" direction, don't go there */ int d1; for (d1=0; d1<4; d1++) { if (d1==d) continue; switch(d1&3) { case 0: /* left */ if (x>1 && !(maze(x-1,y)&RIGHT)) ifindfar(x-1,y,2,r+1); break; case 1: /* up */ if (y>1 && !(maze(x,y-1)&BOTTOM)) ifindfar(x,y-1,3,r+1); break; case 2: /* right */ if (x<w && !(maze(x,y)&RIGHT)) ifindfar(x+1,y,0,r+1); break; case 3: /* down */ if (y<h && !(maze(x,y)&BOTTOM)) ifindfar(x,y+1,1,r+1); break; } } if (x<=1 || x>=w || y<=1 || y>=h) /* on edge? */ if (r>=fardist) {farx=x; fary=y; fardist=r;} } findfar(x,y) { int d; fardist = 0; ifindfar(x,y,4,0); } static unsigned rdm; int random(range) /* Return a number 0..range-1 */ int range; { long n; n = rdm*0xA7A7L; rdm = n+(n>>16)+243; return(rdm%range); } randomize() { #ifdef MSDOS doscall(0x2C00); /* do "get time" call */ rdm = _DX; /* use 1/100ths of a second to randomize */ #else rdm = time(0); #endif }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.