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

Defined functions

drain defined in line 389; used 2 times
icomp defined in line 382; used 2 times
main defined in line 104; never used
near defined in line 368; used 4 times
rin defined in line 347; used 2 times
rline defined in line 320; used 4 times
rnum defined in line 335; used 9 times
tunnel defined in line 298; used 1 times

Defined variables

arrow defined in line 99; used 2 times
intro defined in line 28; used 2 times
loc defined in line 100; used 6 times
room defined in line 26; used 16 times
sccsid defined in line 2; never used
tchar defined in line 102; used 3 times
wloc defined in line 101; used 5 times

Defined struct's

room defined in line 22; used 8 times

Defined macros

BAT defined in line 95; used 5 times
BIGINT defined in line 19; used 1 times
NBAT defined in line 12; used 1 times
NPIT defined in line 15; used 1 times
NROOM defined in line 13; used 14 times
NTUNN defined in line 14; used 13 times
PIT defined in line 96; used 6 times
WUMP defined in line 97; used 8 times
Last modified: 1987-08-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3332
Valid CSS Valid XHTML 1.0 Strict