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