mirror of
https://github.com/bobbimanners/GNO-Extras.git
synced 2024-12-22 17:30:13 +00:00
382 lines
7.2 KiB
Plaintext
382 lines
7.2 KiB
Plaintext
/*
|
|
* wumpus
|
|
* stolen from PCC Vol 2 No 1
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define NBAT 3
|
|
#define NROOM 20
|
|
#define NTUNN 3
|
|
#define NPIT 3
|
|
|
|
struct room
|
|
{
|
|
int tunn[NTUNN];
|
|
int flag;
|
|
} room[NROOM];
|
|
|
|
int rline(void);
|
|
int rnum(int n);
|
|
int tunnel(int i);
|
|
int near(struct room *ap, int ahaz);
|
|
int icomp(int *p1, int *p2);
|
|
int rin(void);
|
|
|
|
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;
|
|
|
|
int main(int argc, char **argv) {
|
|
register i, j;
|
|
register struct room *p;
|
|
int k;
|
|
|
|
struct room *xx;
|
|
k=near(xx, 0); // TEST
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
int tunnel(int 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;
|
|
}
|
|
|
|
int rline(void)
|
|
{
|
|
register char c, r;
|
|
|
|
while((c=getchar()) == ' ');
|
|
r = c;
|
|
while(c != '\n' && c != ' ') {
|
|
if(c == '\0')
|
|
exit(0);
|
|
c = getchar();
|
|
}
|
|
tchar = c;
|
|
return(r);
|
|
}
|
|
|
|
int rnum(int n) {
|
|
static first[2];
|
|
|
|
if(first[1] == 0) {
|
|
time(first);
|
|
srand((first[1]*first[0])^first[1]);
|
|
}
|
|
return((rand()/32768.0) * n);
|
|
}
|
|
|
|
int rin(void)
|
|
{
|
|
register n, c;
|
|
|
|
n = 0;
|
|
c = getchar();
|
|
while(c != '\n' && c != ' ') {
|
|
if(c<'0' || c>'9') {
|
|
while(c != '\n') {
|
|
if(c == 0)
|
|
exit(0);
|
|
c = getchar();
|
|
}
|
|
return(0);
|
|
}
|
|
n = n*10 + c-'0';
|
|
c = getchar();
|
|
}
|
|
return(n);
|
|
}
|
|
|
|
int near(struct room *ap, int ahaz)
|
|
{
|
|
register struct room *p;
|
|
register int haz, i;
|
|
|
|
p = ap;
|
|
haz = ahaz;
|
|
for(i=0; i<NTUNN; i++)
|
|
if(room[p->tunn[i]].flag & haz)
|
|
return (1);
|
|
return(0);
|
|
}
|
|
|
|
int icomp(int *p1, int *p2)
|
|
{
|
|
|
|
return(*p1 - *p2);
|
|
}
|