1 1.12 rillig /* $NetBSD: makemaze.c,v 1.12 2021/05/02 12:50:45 rillig Exp $ */ 2 1.1 mrg /* 3 1.3 wiz * Copyright (c) 1983-2003, Regents of the University of California. 4 1.3 wiz * All rights reserved. 5 1.12 rillig * 6 1.12 rillig * Redistribution and use in source and binary forms, with or without 7 1.12 rillig * modification, are permitted provided that the following conditions are 8 1.3 wiz * met: 9 1.12 rillig * 10 1.12 rillig * + Redistributions of source code must retain the above copyright 11 1.3 wiz * notice, this list of conditions and the following disclaimer. 12 1.12 rillig * + Redistributions in binary form must reproduce the above copyright 13 1.12 rillig * notice, this list of conditions and the following disclaimer in the 14 1.3 wiz * documentation and/or other materials provided with the distribution. 15 1.12 rillig * + Neither the name of the University of California, San Francisco nor 16 1.12 rillig * the names of its contributors may be used to endorse or promote 17 1.12 rillig * products derived from this software without specific prior written 18 1.3 wiz * permission. 19 1.12 rillig * 20 1.12 rillig * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 1.12 rillig * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.12 rillig * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 1.12 rillig * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 1.12 rillig * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 1.12 rillig * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 1.12 rillig * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.12 rillig * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.12 rillig * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.12 rillig * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 1.3 wiz * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 mrg */ 32 1.1 mrg 33 1.2 lukem #include <sys/cdefs.h> 34 1.2 lukem #ifndef lint 35 1.12 rillig __RCSID("$NetBSD: makemaze.c,v 1.12 2021/05/02 12:50:45 rillig Exp $"); 36 1.2 lukem #endif /* not lint */ 37 1.2 lukem 38 1.6 dholland #include "hunt.h" 39 1.1 mrg 40 1.6 dholland #define ISCLEAR(y,x) (Maze[y][x] == SPACE) 41 1.6 dholland #define ODD(n) ((n) & 01) 42 1.1 mrg 43 1.8 joerg #if 0 44 1.1 mrg 45 1.6 dholland #define NPERM 24 46 1.6 dholland #define NDIR 4 47 1.1 mrg 48 1.10 dholland static const int dirs[NPERM][NDIR] = { 49 1.6 dholland {0,1,2,3}, {3,0,1,2}, {0,2,3,1}, {0,3,2,1}, 50 1.6 dholland {1,0,2,3}, {2,3,0,1}, {0,2,1,3}, {2,3,1,0}, 51 1.6 dholland {1,0,3,2}, {1,2,0,3}, {3,1,2,0}, {2,0,3,1}, 52 1.6 dholland {1,3,0,2}, {0,3,1,2}, {1,3,2,0}, {2,0,1,3}, 53 1.6 dholland {0,1,3,2}, {3,1,0,2}, {2,1,0,3}, {1,2,3,0}, 54 1.6 dholland {2,1,3,0}, {3,0,2,1}, {3,2,0,1}, {3,2,1,0} 55 1.6 dholland }; 56 1.6 dholland 57 1.10 dholland static const int incr[NDIR][2] = { 58 1.6 dholland {0, 1}, {1, 0}, {0, -1}, {-1, 0} 59 1.6 dholland }; 60 1.1 mrg 61 1.8 joerg 62 1.1 mrg /* 63 1.1 mrg * candig: 64 1.1 mrg * Is it legal to clear this spot? 65 1.1 mrg */ 66 1.9 dholland static bool 67 1.5 dholland candig(int y, int x) 68 1.1 mrg { 69 1.6 dholland int i; 70 1.1 mrg 71 1.1 mrg if (ODD(x) && ODD(y)) 72 1.9 dholland return false; /* can't touch ODD spots */ 73 1.1 mrg 74 1.1 mrg if (y < UBOUND || y >= DBOUND) 75 1.9 dholland return false; /* Beyond vertical bounds, NO */ 76 1.1 mrg if (x < LBOUND || x >= RBOUND) 77 1.9 dholland return false; /* Beyond horizontal bounds, NO */ 78 1.1 mrg 79 1.1 mrg if (ISCLEAR(y, x)) 80 1.9 dholland return false; /* Already clear, NO */ 81 1.1 mrg 82 1.1 mrg i = ISCLEAR(y, x + 1); 83 1.1 mrg i += ISCLEAR(y, x - 1); 84 1.1 mrg if (i > 1) 85 1.9 dholland return false; /* Introduces cycle, NO */ 86 1.1 mrg i += ISCLEAR(y + 1, x); 87 1.1 mrg if (i > 1) 88 1.9 dholland return false; /* Introduces cycle, NO */ 89 1.1 mrg i += ISCLEAR(y - 1, x); 90 1.1 mrg if (i > 1) 91 1.9 dholland return false; /* Introduces cycle, NO */ 92 1.1 mrg 93 1.9 dholland return true; /* OK */ 94 1.1 mrg } 95 1.11 dholland 96 1.11 dholland static void 97 1.11 dholland dig(int y, int x) 98 1.11 dholland { 99 1.11 dholland const int *dp; 100 1.11 dholland const int *ip; 101 1.11 dholland int ny, nx; 102 1.11 dholland const int *endp; 103 1.11 dholland 104 1.11 dholland Maze[y][x] = SPACE; /* Clear this spot */ 105 1.11 dholland dp = dirs[rand_num(NPERM)]; 106 1.11 dholland endp = &dp[NDIR]; 107 1.11 dholland while (dp < endp) { 108 1.11 dholland ip = &incr[*dp++][0]; 109 1.11 dholland ny = y + *ip++; 110 1.11 dholland nx = x + *ip; 111 1.11 dholland if (candig(ny, nx)) 112 1.11 dholland dig(ny, nx); 113 1.11 dholland } 114 1.11 dholland } 115 1.8 joerg #endif 116 1.1 mrg 117 1.11 dholland static void 118 1.5 dholland dig_maze(int x, int y) 119 1.1 mrg { 120 1.6 dholland int tx, ty; 121 1.6 dholland int i, j; 122 1.6 dholland int order[4]; 123 1.6 dholland #define MNORTH 0x1 124 1.6 dholland #define MSOUTH 0x2 125 1.6 dholland #define MEAST 0x4 126 1.6 dholland #define MWEST 0x8 127 1.1 mrg 128 1.2 lukem tx = ty = 0; 129 1.1 mrg Maze[y][x] = SPACE; 130 1.1 mrg order[0] = MNORTH; 131 1.1 mrg for (i = 1; i < 4; i++) { 132 1.1 mrg j = rand_num(i + 1); 133 1.1 mrg order[i] = order[j]; 134 1.1 mrg order[j] = 0x1 << i; 135 1.1 mrg } 136 1.1 mrg for (i = 0; i < 4; i++) { 137 1.1 mrg switch (order[i]) { 138 1.1 mrg case MNORTH: 139 1.1 mrg tx = x; 140 1.1 mrg ty = y - 2; 141 1.1 mrg break; 142 1.1 mrg case MSOUTH: 143 1.1 mrg tx = x; 144 1.1 mrg ty = y + 2; 145 1.1 mrg break; 146 1.1 mrg case MEAST: 147 1.1 mrg tx = x + 2; 148 1.1 mrg ty = y; 149 1.1 mrg break; 150 1.1 mrg case MWEST: 151 1.1 mrg tx = x - 2; 152 1.1 mrg ty = y; 153 1.1 mrg break; 154 1.1 mrg } 155 1.1 mrg if (tx < 0 || ty < 0 || tx >= WIDTH || ty >= HEIGHT) 156 1.1 mrg continue; 157 1.1 mrg if (Maze[ty][tx] == SPACE) 158 1.1 mrg continue; 159 1.1 mrg Maze[(y + ty) / 2][(x + tx) / 2] = SPACE; 160 1.1 mrg dig_maze(tx, ty); 161 1.1 mrg } 162 1.1 mrg } 163 1.1 mrg 164 1.11 dholland static void 165 1.5 dholland remap(void) 166 1.1 mrg { 167 1.6 dholland int y, x; 168 1.6 dholland char *sp; 169 1.6 dholland int stat; 170 1.1 mrg 171 1.1 mrg for (y = 0; y < HEIGHT; y++) 172 1.1 mrg for (x = 0; x < WIDTH; x++) { 173 1.1 mrg sp = &Maze[y][x]; 174 1.1 mrg if (*sp == SPACE) 175 1.1 mrg continue; 176 1.1 mrg stat = 0; 177 1.1 mrg if (y - 1 >= 0 && Maze[y - 1][x] != SPACE) 178 1.1 mrg stat |= NORTH; 179 1.1 mrg if (y + 1 < HEIGHT && Maze[y + 1][x] != SPACE) 180 1.1 mrg stat |= SOUTH; 181 1.1 mrg if (x + 1 < WIDTH && Maze[y][x + 1] != SPACE) 182 1.1 mrg stat |= EAST; 183 1.1 mrg if (x - 1 >= 0 && Maze[y][x - 1] != SPACE) 184 1.1 mrg stat |= WEST; 185 1.1 mrg switch (stat) { 186 1.1 mrg case WEST | EAST: 187 1.1 mrg case EAST: 188 1.1 mrg case WEST: 189 1.1 mrg *sp = WALL1; 190 1.1 mrg break; 191 1.1 mrg case NORTH | SOUTH: 192 1.1 mrg case NORTH: 193 1.1 mrg case SOUTH: 194 1.1 mrg *sp = WALL2; 195 1.1 mrg break; 196 1.1 mrg case 0: 197 1.6 dholland #ifdef RANDOM 198 1.1 mrg *sp = DOOR; 199 1.6 dholland #endif 200 1.6 dholland #ifdef REFLECT 201 1.1 mrg *sp = rand_num(2) ? WALL4 : WALL5; 202 1.6 dholland #endif 203 1.1 mrg break; 204 1.1 mrg default: 205 1.1 mrg *sp = WALL3; 206 1.1 mrg break; 207 1.1 mrg } 208 1.1 mrg } 209 1.1 mrg memcpy(Orig_maze, Maze, sizeof Maze); 210 1.1 mrg } 211 1.11 dholland 212 1.11 dholland void 213 1.11 dholland makemaze(void) 214 1.11 dholland { 215 1.11 dholland char *sp; 216 1.11 dholland int y, x; 217 1.11 dholland 218 1.11 dholland /* 219 1.11 dholland * fill maze with walls 220 1.11 dholland */ 221 1.11 dholland sp = &Maze[0][0]; 222 1.11 dholland while (sp < &Maze[HEIGHT - 1][WIDTH]) 223 1.11 dholland *sp++ = DOOR; 224 1.11 dholland 225 1.11 dholland x = rand_num(WIDTH / 2) * 2 + 1; 226 1.11 dholland y = rand_num(HEIGHT / 2) * 2 + 1; 227 1.11 dholland dig_maze(x, y); 228 1.11 dholland remap(); 229 1.11 dholland } 230