|
|
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.