home *** CD-ROM | disk | FTP | other *** search
- #
-
- /*
- * wumpus
- * stolen from PCC Vol 2 No 1
- */
-
- #define NBAT 3
- #define NROOM 20
- #define NTUNN 3
- #define NPIT 3
-
- struct room
- {
- int tunn[NTUNN];
- int flag;
- } room[NROOM];
-
- char *intro[]
- {
- "\n",
- "Welcome to 'Hunt the Wumpus.'\n",
- "\n",
- "The Wumpus lives in a cave of %d rooms.\n",
- "Each room has %d tunnels leading to other rooms.\n",
- "\n",
- "Hazards:\n",
- "\n",
- "Bottomless Pits - Some rooms have Bottomless Pits in them.\n",
- " If you go there, you fall into the pit and lose!\n",
- "Super Bats - Some other rooms have super bats.\n",
- " If you go there, a bat will grab you and take you to\n",
- " somewhere else in the cave where you could\n",
- " fall into a pit or run into the . . .\n",
- "\n",
- "Wumpus:\n",
- "\n",
- "The Wumpus is not bothered by the hazards since\n",
- "he has sucker feet and is too big for a bat to lift.\n",
- "\n",
- "Usually he is asleep.\n",
- "Two things wake him up:\n",
- " your entering his room\n",
- " your shooting an arrow anywhere in the cave.\n",
- "If the wumpus wakes, he either decides to move one room or\n",
- "stay where he was. But if he ends up where you are,\n",
- "he eats you up and you lose!\n",
- "\n",
- "You:\n",
- "\n",
- "Each turn you may either move or shoot a crooked arrow.\n",
- "\n",
- "Moving - You can move to one of the adjoining rooms;\n",
- " that is, to one that has a tunnel connecting it with\n",
- " the room you are in.\n",
- "\n",
- "Shooting - You have 5 arrows. You lose when you run out.\n",
- " Each arrow can go from 1 to 5 rooms.\n",
- " You aim by telling the computer\n",
- " The arrow's path is a list of room numbers\n",
- " telling the arrow which room to go to next.\n",
- " The list is terminated with a 0.\n",
- " The first room in the path must be connected to the\n",
- " room you are in. Each succeeding room must be\n",
- " connected to the previous room.\n",
- " If there is no tunnel between two of the rooms\n",
- " in the arrow's path, the arrow chooses one of the\n",
- " three tunnels from the room it's in and goes its\n",
- " own way.\n",
- "\n",
- " If the arrow hits the wumpus, you win!\n",
- " If the arrow hits you, you lose!\n",
- "\n",
- "Warnings:\n",
- "\n",
- "When you are one or two rooms away from the wumpus,\n",
- "the computer says:\n",
- " 'I smell a Wumpus'\n",
- "When you are one room away from some other hazard, it says:\n",
- " Bat - 'Bats nearby'\n",
- " Pit - 'I feel a draft'\n",
- "\n",
- 0,
- };
-
- #define BAT 01
- #define PIT 02
- #define WUMP 04
-
- int arrow;
- int loc;
- int wloc;
- int tchar;
-
- main()
- {
- register i, j;
- register struct room *p;
- int k, icomp();
-
- printf("Instructions? (y-n) ");
- if(rline() == 'y')
- for(i=0; intro[i]; i++)
- printf(intro[i], i&1? NROOM: NTUNN);
-
-
- /*
- * initialize the room connections
- */
-
- init:
- p = &room[0];
- for(i=0; i<NROOM; i++) {
- for(j=0; j<NTUNN; j++)
- p->tunn[j] = -1;
- p++;
- }
- k = 0;
- for(i=1; i<NROOM; ) {
- j = rnum(NROOM);
- p = &room[j];
- if(j == k || p->tunn[0] >= 0 || p->tunn[1] >= 0)
- continue;
- p->tunn[1] = k;
- room[k].tunn[0] = j;
- k = j;
- i++;
- }
- p = &room[0];
- for(i=0; i<NROOM; i++) {
- for(j=0; j<NTUNN; j++) {
- if(p->tunn[j] < 0)
- p->tunn[j] = tunnel(i);
- if(p->tunn[j] == i)
- goto init;
- for(k=0; k<j; k++)
- if(p->tunn[j] == p->tunn[k])
- goto init;
- }
- qsort(&p->tunn[0], NTUNN, 2, icomp);
- p++;
- }
-
- /*
- * put in player, wumpus,
- * pits and bats
- */
-
- setup:
- arrow = 5;
- p = &room[0];
- for(i=0; i<NROOM; i++) {
- p->flag = 0;
- p++;
- }
- for(i=0; i<NPIT; ) {
- p = &room[rnum(NROOM)];
- if((p->flag&PIT) == 0) {
- p->flag =| PIT;
- i++;
- }
- }
- for(i=0; i<NBAT; ) {
- p = &room[rnum(NROOM)];
- if((p->flag&(PIT|BAT)) == 0) {
- p->flag =| BAT;
- i++;
- }
- }
- i = rnum(NROOM);
- wloc = i;
- room[i].flag =| WUMP;
- for(;;) {
- i = rnum(NROOM);
- if((room[i].flag&(PIT|BAT|WUMP)) == 0) {
- loc = i;
- break;
- }
- }
-
- /*
- * main loop of the game
- */
-
- loop:
- printf("You are in room %d\n", loc+1);
- p = &room[loc];
- if(p->flag&PIT) {
- printf("You fell into a pit\n");
- goto done;
- }
- if(p->flag&WUMP) {
- printf("You were eaten by the wumpus\n");
- goto done;
- }
- if(p->flag&BAT) {
- printf("Theres a bat in your room\n");
- loc = rnum(NROOM);
- goto loop;
- }
- for(i=0; i<NTUNN; i++)
- if(near(&room[p->tunn[i]], WUMP))
- goto nearwump;
- if (near(p, WUMP)) {
- nearwump:
- printf("I smell a wumpus\n");
- }
- if (near(p, BAT))
- printf("Bats nearby\n");
- if (near(p, PIT))
- printf("I feel a draft\n");
- printf("There are tunnels to");
- for(i=0; i<NTUNN; i++)
- printf(" %d", p->tunn[i]+1);
- printf("\n");
-
- again:
- printf("Move or shoot (m-s) ");
- switch(rline()) {
- case 'm':
- if(tchar == '\n')
- printf("which room? ");
- i = rin()-1;
- for(j=0; j<NTUNN; j++)
- if(i == p->tunn[j])
- goto groom;
- printf("You hit the wall\n");
- goto again;
- groom:
- loc = i;
- if(i == wloc)
- goto mwump;
- goto loop;
-
- case 's':
- if(tchar == '\n')
- printf("Give list of rooms terminated by 0\n");
- for(i=0; i<5; i++) {
- j = rin()-1;
- if(j == -1)
- break;
- ranarw:
- for(k=0; k<NTUNN; k++)
- if(j == p->tunn[k])
- goto garow;
- j = rnum(NROOM);
- goto ranarw;
- garow:
- p = &room[j];
- if(j == loc) {
- printf("You shot yourself\n");
- goto done;
- }
- if(p->flag&WUMP) {
- printf("You slew the wumpus\n");
- goto done;
- }
- }
- if(--arrow == 0) {
- printf("That was your last shot\n");
- goto done;
- }
- goto mwump;
- }
-
- goto again;
-
- mwump:
- p = &room[wloc];
- p->flag =& ~WUMP;
- i = rnum(NTUNN+1);
- if(i != NTUNN)
- wloc = p->tunn[i];
- room[wloc].flag =| WUMP;
- goto loop;
-
- done:
- printf("Another game? (y-n) ");
- if(rline() == 'y') {
- printf("Same room setup? (y-n) ");
- if(rline() == 'y')
- goto setup;
- goto init;
- }
- }
-
- tunnel(i)
- {
- register struct room *p;
- register n, j;
- int c;
-
- c = 20;
-
- loop:
- n = rnum(NROOM);
- if(n == i)
- if(--c > 0)
- goto loop;
- p = &room[n];
- for(j=0; j<NTUNN; j++)
- if(p->tunn[j] == -1) {
- p->tunn[j] = i;
- return(n);
- }
- goto loop;
- }
-
- rline()
- {
- register char c, r;
-
- while((c=getchar()) == ' ');
- r = c;
- while(c != '\n' && c != ' ') {
- if(c == '\0')
- exit();
- c = getchar();
- }
- tchar = c;
- return(r);
- }
-
- rnum(n)
- {
- static first[2];
-
- if(first[1] == 0) {
- time(first);
- srand((first[1]*first[0])^first[1]);
- }
- return((rand()/32768.0) * n);
- }
-
- rin()
- {
- register n, c;
-
- n = 0;
- c = getchar();
- while(c != '\n' && c != ' ') {
- if(c<'0' || c>'9') {
- while(c != '\n') {
- if(c == 0)
- exit();
- c = getchar();
- }
- return(0);
- }
- n = n*10 + c-'0';
- c = getchar();
- }
- return(n);
- }
-
- near(ap, ahaz)
- struct room *ap;
- {
- register struct room *p;
- register haz, i;
-
- p = ap;
- haz = ahaz;
- for(i=0; i<NTUNN; i++)
- if(room[p->tunn[i]].flag & haz)
- return (1);
- return(0);
- }
-
- icomp(p1, p2)
- int *p1, *p2;
- {
-
- return(*p1 - *p2);
- }
-