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