Research V7 development
[unix-history] / usr / src / games / wump.c
CommitLineData
5d4bc232
KT
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
13struct room
14{
15 int tunn[NTUNN];
16 int flag;
17} room[NROOM];
18
19char *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
90int arrow;
91int loc;
92int wloc;
93int tchar;
94
95main()
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
111init:
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, 2, icomp);
141 p++;
142 }
143
144/*
145 * put in player, wumpus,
146 * pits and bats
147 */
148
149setup:
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
185loop:
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("Theres 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
217again:
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
268mwump:
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
277done:
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
287tunnel(i)
288{
289 register struct room *p;
290 register n, j;
291 int c;
292
293 c = 20;
294
295loop:
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
309rline()
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
324rnum(n)
325{
326 static first[2];
327
328 if(first[1] == 0) {
329 time(first);
330 srand((first[1]*first[0])^first[1]);
331 }
332 return((rand()/32768.0) * n);
333}
334
335rin()
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
356near(ap, ahaz)
357struct 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
370icomp(p1, p2)
371int *p1, *p2;
372{
373
374 return(*p1 - *p2);
375}