1 2 static char sccsid[] = " wump.c 4.1 82/10/24 "; 3 4 # 5 #include <stdio.h> 6 7 /* 8 * wumpus 9 * stolen from PCC Vol 2 No 1 10 */ 11 12 #define NBAT 3 13 #define NROOM 20 14 #define NTUNN 3 15 #define NPIT 3 16 #define BIGINT 2147483648.0 17 18 struct room 19 { 20 int tunn[NTUNN]; 21 int flag; 22 } room[NROOM]; 23 24 char *intro[] = 25 { 26 "\n", 27 "Welcome to 'Hunt the Wumpus.'\n", 28 "\n", 29 "The Wumpus lives in a cave of %d rooms.\n", 30 "Each room has %d tunnels leading to other rooms.\n", 31 "\n", 32 "Hazards:\n", 33 "\n", 34 "Bottomless Pits - Some rooms have Bottomless Pits in them.\n", 35 " If you go there, you fall into the pit and lose!\n", 36 "Super Bats - Some other rooms have super bats.\n", 37 " If you go there, a bat will grab you and take you to\n", 38 " somewhere else in the cave where you could\n", 39 " fall into a pit or run into the . . .\n", 40 "\n", 41 "Wumpus:\n", 42 "\n", 43 "The Wumpus is not bothered by the hazards since\n", 44 "he has sucker feet and is too big for a bat to lift.\n", 45 "\n", 46 "Usually he is asleep.\n", 47 "Two things wake him up:\n", 48 " your entering his room\n", 49 " your shooting an arrow anywhere in the cave.\n", 50 "If the wumpus wakes, he either decides to move one room or\n", 51 "stay where he was. But if he ends up where you are,\n", 52 "he eats you up and you lose!\n", 53 "\n", 54 "You:\n", 55 "\n", 56 "Each turn you may either move or shoot a crooked arrow.\n", 57 "\n", 58 "Moving - You can move to one of the adjoining rooms;\n", 59 " that is, to one that has a tunnel connecting it with\n", 60 " the room you are in.\n", 61 "\n", 62 "Shooting - You have 5 arrows. You lose when you run out.\n", 63 " Each arrow can go from 1 to 5 rooms.\n", 64 " You aim by telling the computer\n", 65 " The arrow's path is a list of room numbers\n", 66 " telling the arrow which room to go to next.\n", 67 " The list is terminated with a 0.\n", 68 " The first room in the path must be connected to the\n", 69 " room you are in. Each succeeding room must be\n", 70 " connected to the previous room.\n", 71 " If there is no tunnel between two of the rooms\n", 72 " in the arrow's path, the arrow chooses one of the\n", 73 " three tunnels from the room it's in and goes its\n", 74 " own way.\n", 75 "\n", 76 " If the arrow hits the wumpus, you win!\n", 77 " If the arrow hits you, you lose!\n", 78 "\n", 79 "Warnings:\n", 80 "\n", 81 "When you are one or two rooms away from the wumpus,\n", 82 "the computer says:\n", 83 " 'I smell a Wumpus'\n", 84 "When you are one room away from some other hazard, it says:\n", 85 " Bat - 'Bats nearby'\n", 86 " Pit - 'I feel a draft'\n", 87 "\n", 88 0, 89 }; 90 91 #define BAT 01 92 #define PIT 02 93 #define WUMP 04 94 95 int arrow; 96 int loc; 97 int wloc; 98 int tchar; 99 100 main() 101 { 102 register i, j; 103 register struct room *p; 104 int k, icomp(); 105 106 printf("Instructions? (y-n) "); 107 if(rline() == 'y') 108 for(i=0; intro[i]; i++) 109 printf(intro[i], i&1? NROOM: NTUNN); 110 111 112 /* 113 * initialize the room connections 114 */ 115 116 init: 117 p = &room[0]; 118 for(i=0; i<NROOM; i++) { 119 for(j=0; j<NTUNN; j++) 120 p->tunn[j] = -1; 121 p++; 122 } 123 k = 0; 124 for(i=1; i<NROOM; ) { 125 j = rnum(NROOM); 126 p = &room[j]; 127 if(j == k || p->tunn[0] >= 0 || p->tunn[1] >= 0) 128 continue; 129 p->tunn[1] = k; 130 room[k].tunn[0] = j; 131 k = j; 132 i++; 133 } 134 p = &room[0]; 135 for(i=0; i<NROOM; i++) { 136 for(j=0; j<NTUNN; j++) { 137 if(p->tunn[j] < 0) 138 p->tunn[j] = tunnel(i); 139 if(p->tunn[j] == i) 140 goto init; 141 for(k=0; k<j; k++) 142 if(p->tunn[j] == p->tunn[k]) 143 goto init; 144 } 145 qsort(&p->tunn[0], NTUNN, sizeof(p->tunn[0]), icomp); 146 p++; 147 } 148 149 /* 150 * put in player, wumpus, 151 * pits and bats 152 */ 153 154 setup: 155 arrow = 5; 156 p = &room[0]; 157 for(i=0; i<NROOM; i++) { 158 p->flag = 0; 159 p++; 160 } 161 for(i=0; i<NPIT; ) { 162 p = &room[rnum(NROOM)]; 163 if((p->flag&PIT) == 0) { 164 p->flag |= PIT; 165 i++; 166 } 167 } 168 for(i=0; i<NBAT; ) { 169 p = &room[rnum(NROOM)]; 170 if((p->flag&(PIT|BAT)) == 0) { 171 p->flag |= BAT; 172 i++; 173 } 174 } 175 i = rnum(NROOM); 176 wloc = i; 177 room[i].flag |= WUMP; 178 for(;;) { 179 i = rnum(NROOM); 180 if((room[i].flag&(PIT|BAT|WUMP)) == 0) { 181 loc = i; 182 break; 183 } 184 } 185 186 /* 187 * main loop of the game 188 */ 189 190 loop: 191 printf("You are in room %d\n", loc+1); 192 p = &room[loc]; 193 if(p->flag&PIT) { 194 printf("You fell into a pit\n"); 195 goto done; 196 } 197 if(p->flag&WUMP) { 198 printf("You were eaten by the wumpus\n"); 199 goto done; 200 } 201 if(p->flag&BAT) { 202 printf("Theres a bat in your room\n"); 203 loc = rnum(NROOM); 204 goto loop; 205 } 206 for(i=0; i<NTUNN; i++) 207 if(near(&room[p->tunn[i]], WUMP)) 208 goto nearwump; 209 if (near(p, WUMP)) { 210 nearwump: 211 printf("I smell a wumpus\n"); 212 } 213 if (near(p, BAT)) 214 printf("Bats nearby\n"); 215 if (near(p, PIT)) 216 printf("I feel a draft\n"); 217 printf("There are tunnels to"); 218 for(i=0; i<NTUNN; i++) 219 printf(" %d", p->tunn[i]+1); 220 printf("\n"); 221 222 again: 223 printf("Move or shoot (m-s) "); 224 switch(rline()) { 225 case 'm': 226 if(tchar == '\n') 227 printf("which room? "); 228 i = rin()-1; 229 for(j=0; j<NTUNN; j++) 230 if(i == p->tunn[j]) 231 goto groom; 232 printf("You hit the wall\n"); 233 goto again; 234 groom: 235 loc = i; 236 if(i == wloc) 237 goto mwump; 238 goto loop; 239 240 case 's': 241 if(tchar == '\n') 242 printf("Give list of rooms terminated by 0\n"); 243 for(i=0; i<5; i++) { 244 j = rin()-1; 245 if(j == -1) 246 break; 247 ranarw: 248 for(k=0; k<NTUNN; k++) 249 if(j == p->tunn[k]) 250 goto garow; 251 j = rnum(NROOM); 252 goto ranarw; 253 garow: 254 p = &room[j]; 255 if(j == loc) { 256 printf("You shot yourself\n"); 257 goto done; 258 } 259 if(p->flag&WUMP) { 260 printf("You slew the wumpus\n"); 261 goto done; 262 } 263 } 264 if(--arrow == 0) { 265 printf("That was your last shot\n"); 266 goto done; 267 } 268 goto mwump; 269 } 270 271 goto again; 272 273 mwump: 274 p = &room[wloc]; 275 p->flag &= ~WUMP; 276 i = rnum(NTUNN+1); 277 if(i != NTUNN) 278 wloc = p->tunn[i]; 279 room[wloc].flag |= WUMP; 280 goto loop; 281 282 done: 283 drain(); 284 printf("Another game? (y-n) "); 285 if(rline() != 'n') { 286 drain(); 287 printf("Same room setup? (y-n) "); 288 if(rline() != 'n') 289 goto setup; 290 goto init; 291 } 292 } 293 294 tunnel(i) 295 { 296 register struct room *p; 297 register n, j; 298 int c; 299 300 c = 20; 301 302 loop: 303 n = rnum(NROOM); 304 if(n == i) 305 if(--c > 0) 306 goto loop; 307 p = &room[n]; 308 for(j=0; j<NTUNN; j++) 309 if(p->tunn[j] == -1) { 310 p->tunn[j] = i; 311 return(n); 312 } 313 goto loop; 314 } 315 316 rline() 317 { 318 register char c, r; 319 320 while((c=getchar()) == ' '); 321 r = c; 322 while(c != '\n' && c != ' ') { 323 if(c == EOF) 324 exit(); 325 c = getchar(); 326 } 327 tchar = c; 328 return(r); 329 } 330 331 rnum(n) 332 { 333 static short first[2]; 334 335 if(first[1] == 0) { 336 time(first); 337 if(first[1]==0) first[1] = 1; 338 srand((first[1]*first[0])^first[1]); 339 } 340 return((int)((rand()/BIGINT) * n)); 341 } 342 343 rin() 344 { 345 register n, c; 346 347 n = 0; 348 c = getchar(); 349 while(c != '\n' && c != ' ') { 350 if(c<'0' || c>'9') { 351 while(c != '\n') { 352 if(c == EOF) 353 exit(); 354 c = getchar(); 355 } 356 return(0); 357 } 358 n = n*10 + c-'0'; 359 c = getchar(); 360 } 361 return(n); 362 } 363 364 near(ap, ahaz) 365 struct room *ap; 366 { 367 register struct room *p; 368 register haz, i; 369 370 p = ap; 371 haz = ahaz; 372 for(i=0; i<NTUNN; i++) 373 if(room[p->tunn[i]].flag & haz) 374 return (1); 375 return(0); 376 } 377 378 icomp(p1, p2) 379 int *p1, *p2; 380 { 381 382 return(*p1 - *p2); 383 } 384 #include <sgtty.h> 385 drain() 386 { 387 register FILE *port = stdin; 388 register int iodes = fileno(port); 389 struct sgttyb arg; 390 391 port->_cnt = 0; 392 port->_ptr = port->_base; 393 if(gtty(iodes,&arg) != -1) stty(iodes,&arg); 394 } 395