Source:NetHack 2.3e/mkmaze.c

Below is the full text to mkmaze.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/mkmaze.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)mkmaze.c	2.3	88/03/31 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include "hack.h"  5.    #include "mkroom.h"		/* not really used */ 6.   extern struct monst *makemon, *mkmon_at; 7.   extern struct permonst pm_wizard; 8.   extern struct obj *mkobj_at, *mksobj_at; 9.   struct permonst hell_hound = 10.  	{ "hell hound", 'd', 12, 14, 2, 20, 3, 6, 0 }; 11.   12.   makemaz 13.  {  14.   	int x,y; 15.  	register zx,zy; 16.  	coord mm; 17.  	boolean al = (dlevel >= 30 && !flags.made_amulet); 18.   19.   	for(x = 2; x < COLNO-1; x++) 20.  		for(y = 2; y < ROWNO-1; y++) 21.  			levl[x][y].typ = (x%2 && y%2) ? 0 : HWALL; 22.  #ifndef RPH 23.  	if(al) { 24.  #else	/* make decoy wizard levels */ 25.  	if((dlevel == u.wiz_level) ||  26.   	   (!rn2(3) && (dlevel > u.medusa_level+1))) { 27.  #endif 28.  	    register struct monst *mtmp; 29.   30.   	    zx = 2*(COLNO/4) - 1; 31.  	    zy = 2*(ROWNO/4) - 1; 32.  	    for(x = zx-2; x < zx+4; x++) for(y = zy-2; y <= zy+2; y++) { 33.  		levl[x][y].typ = 34.  		    (y == zy-2 || y == zy+2 || x == zx-2 || x == zx+3) ? POOL : 35.  		    (y == zy-1 || y == zy+1 || x == zx-1 || x == zx+2) ? HWALL: 36.  		    ROOM; 37.  	    }  38.   #ifdef RPH 39.  	    if (dlevel == u.wiz_level) { 40.  #endif 41.  		    (void) mkobj_at(AMULET_SYM, zx, zy); 42.  		    flags.made_amulet = 1; 43.  		    walkfrom(zx+4, zy); 44.  		    if(mtmp = makemon(&hell_hound, zx, zy)) 45.  			mtmp->msleep = 1; 46.  		    if(mtmp = makemon(PM_WIZARD, zx+1, zy)) { 47.  			mtmp->msleep = 1; 48.  			flags.no_of_wizards = 1; 49.  		    }  50.   #ifdef RPH 51.  	    } else { 52.  		struct obj *ot; 53.  	    	/* make a cheap plastic imitation */ 54.  	    	if (ot = mkobj_at(AMULET_SYM, zx, zy)) 55.  		    ot-> spe = -1; 56.  		walkfrom(zx+4,zy); 57.  		if (mtmp = makemon(&hell_hound, zx, zy)) 58.  		    mtmp->msleep = 1; 59.  		mkmon_at ('&', zx+1,zy); 60.  	    }  61.   #endif 62.  	} else { 63.  	    mazexy(&mm); 64.  	    zx = mm.x;  65. zy = mm.y; 66. walkfrom(zx,zy); 67.  #ifdef RPH 68.  	    if (!rn2(10) || (dlevel == u.medusa_level + 1)) 69.  #endif 70.  		(void) mksobj_at(WAN_WISHING, zx, zy); 71.  	    (void) mkobj_at(ROCK_SYM, zx, zy);	/* put a rock on top of it */ 72.  	}  73.    74.   	for(x = 2; x < COLNO-1; x++) 75.  		for(y = 2; y < ROWNO-1; y++) { 76.  			switch(levl[x][y].typ) { 77.  			case HWALL: 78.  				levl[x][y].scrsym = HWALL_SYM; 79.  				break; 80.  			case ROOM: 81.  				levl[x][y].scrsym = ROOM_SYM; 82.  				break; 83.  			}  84.   		}  85.   	for(x = rn1(8,11); x; x--) { 86.  		mazexy(&mm); 87.  		(void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y); 88.  	}  89.   	for(x = rn1(10,2); x; x--) { 90.  		mazexy(&mm); 91.  		(void) mkobj_at(ROCK_SYM, mm.x, mm.y); 92.  	}  93.   	mazexy(&mm); 94.  	(void) makemon(PM_MINOTAUR, mm.x, mm.y); 95.  	for(x = rn1(5,7); x; x--) { 96.  		mazexy(&mm); 97.  		(void) makemon((struct permonst *) 0, mm.x, mm.y); 98.  	}  99.   	for(x = rn1(6,7); x; x--) { 100. 		mazexy(&mm); 101. 		mkgold(0L,mm.x,mm.y); 102. 	}  103.  	for(x = rn1(6,7); x; x--) 104. 		mktrap(0,1,(struct mkroom *) 0); 105. 	mazexy(&mm); 106. 	levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = UP_SYM; 107. 	levl[xupstair][yupstair].typ = STAIRS; 108. 	xdnstair = ydnstair = 0; 109. }  110.   111.  #ifdef DGK 112. /* Make the mazewalk iterative by faking a stack. This is needed to 113. * ensure the mazewalk is successful in the limited stack space of 114. * the program. This iterative version uses the mimumum amount of stack 115.  * that is totally safe. 116.  */  117.  walkfrom(x,y) 118. int x,y; 119. {  120.  #define CELLS (ROWNO * COLNO) / 4		/* a maze cell is 4 squares */ 121. 	char mazex[CELLS + 1], mazey[CELLS + 1];	/* char's are OK */ 122. 	int q, a, dir, pos; 123. 	int dirs[4]; 124.  125.  	pos = 1; 126. 	mazex[pos] = (char) x;  127. mazey[pos] = (char) y; 128. while (pos) { 129. 		x = (int) mazex[pos]; 130. 		y = (int) mazey[pos]; 131. 		levl[x][y].typ = ROOM; 132. 		q = 0; 133. 		for (a = 0; a < 4; a++) 134. 			if(okay(x, y, a)) dirs[q++]= a;  135. if (!q) 136. 			pos--; 137. 		else { 138. 			dir = dirs[rn2(q)]; 139. 			move(&x, &y, dir); 140. 			levl[x][y].typ = ROOM; 141. 			move(&x, &y, dir); 142. 			pos++; 143. 			if (pos > CELLS) 144. 				panic("Overflow in walkfrom"); 145. 			mazex[pos] = (char) x;  146. mazey[pos] = (char) y; 147. } 148.  	}  149.  }  150.  #else 151.  152.  walkfrom(x,y) int x,y; { 153. register int q,a,dir; 154. int dirs[4]; 155. 	levl[x][y].typ = ROOM; 156. 	while(1) { 157. 		q = 0; 158. 		for(a = 0; a < 4; a++) 159. 			if(okay(x,y,a)) dirs[q++]= a;  160. if(!q) return; 161. 		dir = dirs[rn2(q)]; 162. 		move(&x,&y,dir); 163. 		levl[x][y].typ = ROOM; 164. 		move(&x,&y,dir); 165. 		walkfrom(x,y); 166. 	}  167.  }  168.  #endif /* DGK /**/ 169.  170.  move(x,y,dir) 171. register int *x, *y; 172. register int dir; 173. {  174.  	switch(dir){ 175. 		case 0: --(*y); break; 176. 		case 1: (*x)++; break; 177. 		case 2: (*y)++; break; 178. 		case 3: --(*x); break; 179. 	}  180.  }  181.   182.  okay(x,y,dir) 183. int x,y; 184. register int dir; 185. {  186.  	move(&x,&y,dir); 187. 	move(&x,&y,dir); 188. 	if(x<3 || y<3 || x>COLNO-3 || y>ROWNO-3 || levl[x][y].typ != 0) 189. 		return(0); 190. 	else 191. 		return(1); 192. }  193.   194.  mazexy(cc) 195. coord	*cc; 196. {  197.  	cc->x = 3 + 2*rn2(COLNO/2 - 2); 198. 	cc->y = 3 + 2*rn2(ROWNO/2 - 2); 199. 	return(0); 200. }