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: }

Defined functions

drain defined in line 385; used 2 times
icomp defined in line 378; used 2 times
main defined in line 100; never used
near defined in line 364; used 4 times
rin defined in line 343; used 2 times
rline defined in line 316; used 4 times
rnum defined in line 331; used 9 times
tunnel defined in line 294; used 1 times

Defined variables

arrow defined in line 95; used 2 times
intro defined in line 24; used 2 times
loc defined in line 96; used 6 times
room defined in line 22; used 16 times
sccsid defined in line 2; never used
tchar defined in line 98; used 3 times
wloc defined in line 97; used 5 times

Defined struct's

room defined in line 18; used 8 times

Defined macros

BAT defined in line 91; used 5 times
BIGINT defined in line 16; 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 92; used 6 times
WUMP defined in line 93; used 8 times
Last modified: 1982-10-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 992
Valid CSS Valid XHTML 1.0 Strict