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