|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.