1: /* 2: * Hunt 3: * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold 4: * San Francisco, California 5: * 6: * Copyright (c) 1985 Regents of the University of California. 7: * All rights reserved. The Berkeley software License Agreement 8: * specifies the terms and conditions for redistribution. 9: */ 10: 11: # include "hunt.h" 12: 13: # define ISCLEAR(y,x) (Maze[y][x] == SPACE) 14: # define ODD(n) ((n) & 01) 15: 16: makemaze() 17: { 18: register char *sp; 19: register int y, x; 20: 21: /* 22: * fill maze with walls 23: */ 24: sp = &Maze[0][0]; 25: while (sp < &Maze[HEIGHT - 1][WIDTH]) 26: *sp++ = DOOR; 27: 28: y = rand_num(DBOUND - UBOUND) + UBOUND; 29: x = rand_num(RBOUND - LBOUND) + LBOUND; 30: dig(y, x); /* Dig out the maze */ 31: remap(); 32: } 33: 34: # define NPERM 24 35: # define NDIR 4 36: 37: int dirs[NPERM][NDIR] = { 38: {0,1,2,3}, {3,0,1,2}, {0,2,3,1}, {0,3,2,1}, 39: {1,0,2,3}, {2,3,0,1}, {0,2,1,3}, {2,3,1,0}, 40: {1,0,3,2}, {1,2,0,3}, {3,1,2,0}, {2,0,3,1}, 41: {1,3,0,2}, {0,3,1,2}, {1,3,2,0}, {2,0,1,3}, 42: {0,1,3,2}, {3,1,0,2}, {2,1,0,3}, {1,2,3,0}, 43: {2,1,3,0}, {3,0,2,1}, {3,2,0,1}, {3,2,1,0} 44: }; 45: 46: int incr[NDIR][2] = { 47: {0, 1}, {1, 0}, {0, -1}, {-1, 0} 48: }; 49: 50: dig(y, x) 51: int y, x; 52: { 53: register int *dp; 54: register int *ip; 55: register int ny, nx; 56: register int *endp; 57: 58: Maze[y][x] = SPACE; /* Clear this spot */ 59: dp = dirs[rand_num(NPERM)]; 60: endp = &dp[NDIR]; 61: while (dp < endp) { 62: ip = &incr[*dp++][0]; 63: ny = y + *ip++; 64: nx = x + *ip; 65: if (candig(ny, nx)) 66: dig(ny, nx); 67: } 68: } 69: 70: /* 71: * candig: 72: * Is it legal to clear this spot? 73: */ 74: candig(y, x) 75: register int y, x; 76: { 77: register int i; 78: 79: if (ODD(x) && ODD(y)) 80: return FALSE; /* can't touch ODD spots */ 81: 82: if (y < UBOUND || y >= DBOUND) 83: return FALSE; /* Beyond vertical bounds, NO */ 84: if (x < LBOUND || x >= RBOUND) 85: return FALSE; /* Beyond horizontal bounds, NO */ 86: 87: if (ISCLEAR(y, x)) 88: return FALSE; /* Already clear, NO */ 89: 90: i = ISCLEAR(y, x + 1); 91: i += ISCLEAR(y, x - 1); 92: if (i > 1) 93: return FALSE; /* Introduces cycle, NO */ 94: i += ISCLEAR(y + 1, x); 95: if (i > 1) 96: return FALSE; /* Introduces cycle, NO */ 97: i += ISCLEAR(y - 1, x); 98: if (i > 1) 99: return FALSE; /* Introduces cycle, NO */ 100: 101: return TRUE; /* OK */ 102: } 103: 104: remap() 105: { 106: register int y, x; 107: register char *sp; 108: register int stat; 109: 110: for (y = 0; y < HEIGHT; y++) 111: for (x = 0; x < WIDTH; x++) { 112: sp = &Maze[y][x]; 113: if (*sp == SPACE) 114: continue; 115: stat = 0; 116: if (y - 1 >= 0 && Maze[y - 1][x] != SPACE) 117: stat |= NORTH; 118: if (y + 1 < HEIGHT && Maze[y + 1][x] != SPACE) 119: stat |= SOUTH; 120: if (x + 1 < WIDTH && Maze[y][x + 1] != SPACE) 121: stat |= EAST; 122: if (x - 1 >= 0 && Maze[y][x - 1] != SPACE) 123: stat |= WEST; 124: switch (stat) { 125: case WEST | EAST: 126: *sp = WALL1; 127: break; 128: case NORTH | SOUTH: 129: *sp = WALL2; 130: break; 131: case 0: 132: # ifdef RANDOM 133: *sp = DOOR; 134: # endif RANDOM 135: # ifdef REFLECT 136: *sp = rand_num(2) ? WALL4 : WALL5; 137: # endif REFLECT 138: break; 139: default: 140: *sp = WALL3; 141: break; 142: } 143: } 144: bcopy((char *) Maze, (char *) Orig_maze, sizeof Maze); 145: }