21e56e8eb82c9791cd93a06cdc69031318fb7d60
[wumpus.git] / wumpus.c
1 /*
2  * wumpus.c --- a faithful translation of the classic "Hunt The Wumpus" game.
3  *
4  * Translator: Eric S. Raymond <eric@snark.thyrsus.com>
5  * Version: $Id$
6  *
7  * This was the state of the art 20 years ago, in 1972.  We've come a long
8  * way, baby.
9  *
10  * The BASIC source is that posted by Magnus Olsson in USENET article
11  * <9207071854.AA21847@thep.lu.se>: he wrote
12  *
13  * >Below is the source code for _one_ (rather simple) Wumpus version,
14  * >which I found in the PC-BLUE collection on SIMTEL20. I believe this is
15  * >pretty much the same version that was published in David Ahl's "101
16  * >Basic Computer Games" (or, possibly, in the sequel). 
17  *
18  * I have staunchly resisted the temptation to "improve" this game.  It
19  * is functionally identical to the BASIC version (source for which
20  * appears in the comments).  I fixed some typos in the help text.
21  *
22  * Language hackers may be interested to know that he most difficult thing
23  * about the translation was tracking the details required to translate from
24  * 1-origin to 0-origin array indexing.
25  *
26  * The only enhancement is a an -s command-line switch for setting the
27  * random number seed.
28  *
29  * So, pretend for a little while that your workstation is an ASR-33 and
30  * limber up your fingers for a trip to nostalgia-land...
31  */
32
33 #include <stdio.h>
34
35 /* 5 REM *** HUNT THE WUMPUS ***                                        */
36
37 /* 10 DIM P(5)                                                          */
38 static int path[5];
39
40 static int j, k, arrows, scratchloc;
41 static char inp[BUFSIZ];                /* common input buffer */
42
43 #define YOU     0
44 #define WUMPUS  1
45 #define PIT1    2
46 #define PIT2    3
47 #define BATS1   4
48 #define BATS2   5
49 #define LOCS    6
50 static int loc[LOCS], save[LOCS];       /* locations */
51
52 #define NOT     0
53 #define WIN     1
54 #define LOSE    -1
55 static int finished;
56
57 /* 80 REM *** SET UP CAVE (DODECAHEDRAL NODE LIST) ***          */
58 /* 85 DIM S(20,3)                                                       */
59 /* 90 FOR J=1 TO 20                                                     */
60 /* 95 FOR K=1 TO 3                                                      */
61 /* 100 READ S(J,K)                                                      */
62 /* 105 NEXT K                                                   */
63 /* 110 NEXT J                                                   */
64 /* 115 DATA 2,5,8,1,3,10,2,4,12,3,5,14,1,4,6                    */
65 /* 120 DATA 5,7,15,6,8,17,1,7,9,8,10,18,2,9,11                  */
66 /* 125 DATA 10,12,19,3,11,13,12,14,20,4,13,15,6,14,16           */
67 /* 130 DATA 15,17,20,7,16,18,9,17,19,11,18,20,13,16,19          */
68 static int cave[20][3] =
69 {
70     {1,4,7},
71     {0,2,9},
72     {1,3,11},
73     {2,4,13},
74     {0,3,5},
75     {4,6,14},
76     {5,7,16},
77     {0,6,8},
78     {7,9,17},
79     {1,8,10},
80     {9,11,18},
81     {2,10,12},
82     {11,13,19},
83     {3,12,14},
84     {5,13,15},
85     {14,16,19},
86     {6,15,17},
87     {8,16,18},
88     {10,17,19},
89     {12,15,18},
90 };
91
92 /* 135 DEF FNA(X)=INT(20*RND(1))+1                                      */
93 #define FNA() (rand() % 20) 
94
95 /* 140 DEF FNB(X)=INT(3*RND(1))+1                                       */
96 #define FNB() (rand() % 3) 
97
98 /* 145 DEF FNC(X)=INT(4*RND(1))+1                                       */
99 #define FNC() (rand() % 4) 
100
101 int getnum(prompt)
102 char *prompt;
103 {
104     (void) printf("%s\n?", prompt);
105     (void) fgets(inp, sizeof(inp), stdin);
106     return(atoi(inp));
107 }
108
109 int getlet(prompt)
110 char *prompt;
111 {
112     (void) printf("%s\n?", prompt);
113     (void) fgets(inp, sizeof(inp), stdin);
114     return(inp[0]);    
115 }
116
117 void print_instructions()
118 {
119     char ebuf[BUFSIZ];
120
121 /* 375 REM *** INSTRUCTIONS ***                                         */
122 /* 380 PRINT "WELCOME TO 'HUNT THE WUMPUS'"                             */
123     puts("WELCOME TO 'HUNT THE WUMPUS'");
124 /* 385 PRINT "  THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM"      */
125     puts("  THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM");
126 /* 390 PRINT "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A"         */
127     puts("HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A");
128 /* 395 PRINT "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW"     */
129     puts("DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW");
130 /* 400 PRINT "WHAT A DODECAHEDRON IS, ASK SOMEONE)"                     */
131     puts("WHAT A DODECAHEDRON IS, ASK SOMEONE)");
132 /* 405 PRINT                                                            */
133     puts("");
134 /* 410 PRINT "     HAZARDS:"                                            */
135     puts("     HAZARDS:");
136 /* 415 PRINT " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM */
137     puts(" BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM");
138 /* 420 PRINT "     IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)"    */
139     puts("     IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)");
140 /* 425 PRINT " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU"    */
141     puts(" SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU");
142 /* 430 PRINT "     GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER"       */
143     puts("     GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER");
144 /* 435 PRINT "     ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)"          */
145     puts("     ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)");
146 /* 440 INPUT "TYPE AN E THEN RETURN ";W9                                */
147     (void) getlet("TYPE AN E THEN RETURN ");
148 /* 445 PRINT "     WUMPUS:"                                             */
149     puts("     WUMPUS:");
150 /* 450 PRINT " THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER"    */
151     puts(" THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER");
152 /* 455 PRINT " FEET AND IS TOO BIG FOR A BAT TO LIFT).  USUALLY"        */
153     puts(" FEET AND IS TOO BIG FOR A BAT TO LIFT).  USUALLY");
154 /* 460 PRINT " HE IS ASLEEP.  TWO THINGS WAKE HIM UP: YOU SHOOTING AN"  */
155     puts(" HE IS ASLEEP.  TWO THINGS WAKE HIM UP: YOU SHOOTING AN");
156 /* 465 PRINT "ARROW OR YOU ENTERING HIS ROOM."                          */
157     puts("ARROW OR YOU ENTERING HIS ROOM.");
158 /* 470 PRINT "     IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM"       */
159     puts("     IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM");
160 /* 475 PRINT " OR STAYS STILL (P=.25).  AFTER THAT, IF HE IS WHERE YOU" */
161     puts(" OR STAYS STILL (P=.25).  AFTER THAT, IF HE IS WHERE YOU");
162 /* 480 PRINT " ARE, HE EATS YOU UP AND YOU LOSE!"                       */
163     puts(" ARE, HE EATS YOU UP AND YOU LOSE!");
164 /* 485 PRINT                                                            */
165     puts("");
166 /* 490 PRINT "     YOU:"                                                */
167     puts("     YOU:");
168 /* 495 PRINT " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW"         */
169     puts(" EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW");
170 /* 500 PRINT "   MOVING:  YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)"      */
171     puts("   MOVING:  YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)");
172 /* 505 PRINT "   ARROWS:  YOU HAVE 5 ARROWS.  YOU LOSE WHEN YOU RUN OUT */
173     puts("   ARROWS:  YOU HAVE 5 ARROWS.  YOU LOSE WHEN YOU RUN OUT");
174 /* 510 PRINT "   EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING*/
175     puts("   EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING");
176 /* 515 PRINT "   THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO."  */
177     puts("   THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO.");
178 /* 520 PRINT "   IF THE ARROW CAN'T GO THAT WAY (IF NO TUNNEL) IT MOVES"*/
179     puts("   IF THE ARROW CAN'T GO THAT WAY (IF NO TUNNEL) IT MOVES");
180 /* 525 PRINT "   AT RANDOM TO THE NEXT ROOM."                           */
181     puts("   AT RANDOM TO THE NEXT ROOM.");
182 /* 530 PRINT "     IF THE ARROW HITS THE WUMPUS, YOU WIN."              */
183     puts("     IF THE ARROW HITS THE WUMPUS, YOU WIN.");
184 /* 535 PRINT "     IF THE ARROW HITS YOU, YOU LOSE."                    */
185     puts("     IF THE ARROW HITS YOU, YOU LOSE.");
186 /* 540 INPUT "TYPE AN E THEN RETURN ";W9                                */
187     (void) getlet("TYPE AN E THEN RETURN ");
188 /* 545 PRINT "    WARNINGS:"                                            */
189     puts("    WARNINGS:");
190 /* 550 PRINT "     WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD," */
191     puts("     WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD,");
192 /* 555 PRINT "     THE COMPUTER SAYS:"                                  */
193     puts("     THE COMPUTER SAYS:");
194 /* 560 PRINT " WUMPUS:  'I SMELL A WUMPUS'"                             */
195     puts(" WUMPUS:  'I SMELL A WUMPUS'");
196 /* 565 PRINT " BAT   :  'BATS NEARBY'"                                  */
197     puts(" BAT   :  'BATS NEARBY'");
198 /* 570 PRINT " PIT   :  'I FEEL A DRAFT'"                               */
199     puts(" PIT   :  'I FEEL A DRAFT'");
200 /* 575 PRINT                                                            */
201     puts("");
202 /* 580 RETURN                                                           */
203 }
204
205 void check_hazards()
206 {
207     /* 585 REM *** PRINT LOCATION & HAZARD WARNINGS ***                 */
208     /* 590 PRINT                                                        */
209     (void) puts("");
210
211     /* 595 FOR J=2 TO 6                                                 */
212     /* 600 FOR K=1 TO 3                                                 */
213     /* 605 IF S(L(1),K)<>L(J) THEN 640                                  */
214     /* 610 ON J-1 GOTO 615,625,625,635,635                              */
215     /* 615 PRINT "I SMELL A WUMPUS!"                                    */
216     /* 620 GOTO 640                                                     */
217     /* 625 PRINT "I FEEL A DRAFT"                                       */
218     /* 630 GOTO 640                                                     */
219     /* 635 PRINT "BATS NEARBY!"                                         */
220     /* 640 NEXT K                                                       */
221     /* 645 NEXT J                                                       */
222     for (k = 0; k < 3; k++)
223     {
224         int room = cave[loc[YOU]][k];
225
226         if (room == loc[WUMPUS])
227             (void) puts("I SMELL A WUMPUS!");
228         else if (room == loc[PIT1] || room == loc[PIT2])
229             (void) puts("I FEEL A DRAFT");
230         else if (room == loc[BATS1] || room == loc[BATS2])
231             (void) puts("BATS NEARBY!");
232     }
233
234     /* 650 PRINT "YOU ARE IN ROOM "L(1)                                 */
235     (void) printf("YOU ARE IN ROOM %d\n", loc[YOU]+1);
236
237     /* 655 PRINT "TUNNELS LEAD TO "S(L,1);S(L,2);S(L,3)                 */
238     (void) printf("TUNNELS LEAD TO %d %d %d\n",
239                   cave[loc[YOU]][0]+1, cave[loc[YOU]][1]+1, cave[loc[YOU]][2]+1);
240
241     /* 660 PRINT                                                        */
242     (void) puts("");
243
244     /* 665 RETURN                                                       */
245 }
246
247 int move_or_shoot()
248 {
249     int c;
250
251     /* 670 REM *** CHOOSE OPTION ***                                    */
252
253 badin:
254     /* 675 PRINT "SHOOT OR MOVE (S-M)";                                 */
255     /* 680 INPUT I$                                                     */
256     c = getlet("SHOOT OR MOVE (S-M)");
257
258     /* 685 IF I$<>"S" THEN 700                                          */
259     /* 690 O=1                                                          */
260     /* 695 RETURN                                                       */
261     /* 700 IF I$<>"M" THEN 675                                          */
262     /* 705 O=2                                                          */
263     /* 710 RETURN                                                       */
264     if (c == 'S')
265         return(1);
266     else if (c == 'M')
267         return(0);
268     else
269         goto badin;
270 }
271
272
273
274 void shoot()
275 {
276     extern void check_shot(), move_wumpus();
277     int j9;
278
279     /* 715 REM *** ARROW ROUTINE ***                                    */
280     /* 720 F=0                                                          */
281     finished = NOT;
282
283     /* 725 REM *** PATH OF ARROW ***                                    */
284 badrange:
285     /* 735 PRINT "NO. OF ROOMS (1-5)";                                  */
286     /* 740 INPUT J9                                                     */
287     j9 = getnum("NO. OF ROOMS (1-5)");
288
289     /* 745 IF J9<1 THEN 735                                             */
290     /* 750 IF J9>5 THEN 735                                             */
291     if (j9 < 1 || j9 > 5)
292         goto badrange;
293
294     /* 755 FOR K=1 TO J9                                                */
295     for (k = 0; k < j9; k++)
296     {
297         /* 760 PRINT "ROOM #";                                          */
298         /* 765 INPUT P(K)                                               */
299         path[k] = getnum("ROOM #") - 1;
300
301         /* 770 IF K<=2 THEN 790                                         */
302         if (k <= 1)
303             continue;
304
305         /* 775 IF P(K)<>P(K-2) THEN 790                                 */
306         if (path[k] != path[k - 2])
307             continue;
308
309         /* 780 PRINT "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM"    */
310         (void) puts("ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM");
311         /* 785 GOTO 760                                                 */
312         k--;
313
314         /* 790 NEXT K                                                   */
315     }
316
317     /* 795 REM *** SHOOT ARROW ***                                      */
318     /* 800 L=L(1)                                                       */
319     scratchloc = loc[YOU];
320
321     /* 805 FOR K=1 TO J9                                                */
322     for (k = 0; k < j9; k++)
323     {
324         int     k1;
325
326         /* 810 FOR K1=1 TO 3                                            */
327         for (k1 = 0; k1 < 3; k1++)
328         {
329             /* 815 IF S(L,K1)=P(K) THEN 895                             */
330             if (cave[scratchloc][k1] == path[k])
331             {
332                 /*
333                  * This is the only bit of the translation I'm not sure
334                  * about.  It requires the trajectory of the arrow to
335                  * be a path.  Without it, all rooms on the trajectory
336                  * would be required by the above to be adjacent to the
337                  * player, making for a trivial game --- just move to where
338                  * you smell a wumpus and shoot into all adjacent passages!
339                  * However, I can't find an equivalent in the BASIC.
340                  */
341                 scratchloc = path[k];
342
343                 /* this simulates logic at 895 in the BASIC code */
344                 check_shot();
345                 if (finished == NOT)
346                     goto ammo;
347                 else
348                     return;
349             }
350
351             /* 820 NEXT K1                                              */
352         }
353
354         /* 825 REM *** NO TUNNEL FOR ARROW ***                          */
355         /* 830 L=S(L,FNB(1))                                            */
356         scratchloc = cave[scratchloc][FNB()];
357
358         /* 835 GOTO 900                                                 */
359         check_shot();
360
361         /* 840 NEXT K                                                   */
362     }
363
364 ammo:
365     if (finished == NOT)
366     {
367         /* 845 PRINT "MISSED"                                           */
368         (void) puts("MISSED");
369
370         /* 850 L=L(1)                                                   */
371         scratchloc = loc[YOU];
372
373         /* 855 REM *** MOVE WUMPUS ***                                  */
374         /* 860 GOSUB 935                                                */
375         move_wumpus();
376
377         /* 865 REM *** AMMO CHECK ***                                   */
378         /* 870 A=A-1                                                    */
379         /* 875 IF A>0 THEN 885                                          */
380         /* 880 F=-1                                                     */
381         if (--arrows <= 0)
382             finished = LOSE;
383     }
384
385     /* 885 RETURN                                                       */
386 }
387
388 void check_shot()
389 {
390     /* 890 REM *** SEE IF ARROW IS AT L(1) OR AT L(2)                   */
391     /* 895 L=P(K)                                                       */
392
393     /* 900 IF L<>L(2) THEN 920                                          */
394     /* 905 PRINT "AHA! YOU GOT THE WUMPUS!"                             */
395     /* 910 F=1                                                          */
396     /* 915 RETURN                                                       */
397     if (scratchloc == loc[WUMPUS])
398     {
399         (void) puts("AHA! YOU GOT THE WUMPUS!");
400         finished = WIN;
401     }
402
403     /* 920 IF L<>L(1) THEN 840                                          */
404     /* 925 PRINT "OUCH! ARROW GOT YOU!"                                 */
405     /* 930 GOTO 880                                                     */
406     else if (scratchloc == loc[YOU])
407     {
408         (void) puts("OUCH! ARROW GOT YOU!");
409         finished = LOSE;
410     }
411 }
412
413 void move_wumpus()
414 {
415     /* 935 REM *** MOVE WUMPUS ROUTINE ***                              */
416     /* 940 K=FNC(0)                                                     */
417     k = FNC();
418
419     /* 945 IF K=4 THEN 955                                              */
420     /* 950 L(2)=S(L(2),K)                                               */
421     if (k < 3)
422         loc[WUMPUS] = cave[loc[WUMPUS]][k];
423
424     /* 955 IF L(2)<>L THEN 970                                          */
425     if (loc[WUMPUS] != loc[YOU])
426         return;
427
428     /* 960 PRINT "TSK TSK TSK - WUMPUS GOT YOU!"                        */
429     (void) puts("TSK TSK TSK - WUMPUS GOT YOU!");
430
431     /* 965 F=-1                                                         */
432     finished = LOSE;
433
434     /* 970 RETURN                                                       */
435 }
436
437 void move()
438 {
439     /* 975 REM *** MOVE ROUTINE ***                                     */
440     /* 980 F=0                                                          */
441     finished = NOT;
442
443 badmove:
444     /* 985 PRINT "WHERE TO";                                            */
445     /* 990 INPUT L                                                      */
446     scratchloc = getnum("WHERE TO");
447
448     /* 995 IF L<1 THEN 985                                              */
449     /* 1000 IF L>20 THEN 985                                            */
450     if (scratchloc < 1 || scratchloc > 20)
451         goto badmove;
452     scratchloc--;
453
454     /* 1005 FOR K=1 TO 3                                                */
455     for (k = 0; k < 3; k++)
456     {
457         /* 1010 REM *** CHECK IF LEGAL MOVE ***                         */
458         /* 1015 IF S(L(1),K)=L THEN 1045                                */
459         if (cave[loc[YOU]][k] == scratchloc)
460             goto goodmove;
461
462         /* 1020 NEXT K                                                  */
463     }
464
465     /* 1025 IF L=L(1) THEN 1045                                         */
466     if (scratchloc != loc[YOU])
467     {
468         /* 1030 PRINT "NOT POSSIBLE -";                                 */
469         (void) puts("NOT POSSIBLE -");
470
471         /* 1035 GOTO 985                                                */
472         goto badmove;
473     }
474
475 goodmove:
476     /* 1040 REM *** CHECK FOR HAZARDS ***                               */
477     /* 1045 L(1)=L                                                      */
478     loc[YOU] = scratchloc;
479
480     if (scratchloc == loc[WUMPUS])
481     {
482         /* 1050 REM *** WUMPUS ***                                      */
483         /* 1055 IF L<>L(2) THEN 1090                                    */
484         /* 1060 PRINT "... OOPS! BUMPED A WUMPUS!"                      */
485         /* 1065 REM *** MOVE WUMPUS ***                                 */
486         /* 1070 GOSUB 940                                               */
487         /* 1075 IF F=0 THEN 1090                                        */
488         /* 1080 RETURN                                                  */
489         (void) puts("... OOPS! BUMPED A WUMPUS!");
490         move_wumpus();
491     }
492     else if (scratchloc == loc[PIT1] || scratchloc == loc[PIT2])
493     {
494         /* 1085 REM *** PIT ***                                         */
495         /* 1090 IF L=L(3) THEN 1100                                     */
496         /* 1095 IF L<>L(4) THEN 1120                                    */
497         /* 1100 PRINT "YYYYIIIIEEEE . . . FELL IN PIT"                  */
498         /* 1105 F=-1                                                    */
499         /* 1110 RETURN                                                  */
500         (void) puts("YYYYIIIIEEEE . . . FELL IN PIT");
501         finished = LOSE;
502     }
503     else if (scratchloc == loc[BATS1] || scratchloc == loc[BATS2])
504     {
505         /* 1115 REM *** BATS ***                                        */
506         /* 1120 IF L=L(5) THEN 1130                                     */
507         /* 1125 IF L<>L(6) THEN 1145                                    */
508         /* 1130 PRINT "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!"  */
509         /* 1135 L=FNA(1)                                                */
510         /* 1140 GOTO 1045                                               */
511         /* 1145 RETURN                                                  */
512         /* 1150 END                                                     */
513         (void) puts("ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!");
514         loc[YOU] = FNA();
515     }
516 }
517
518 main(argc, argv)
519 int argc;
520 char *argv[];
521 {
522     int c;
523
524     if (strcmp(argv[1], "-s") == 0)
525         srand(atol(argv[2]));
526     else
527         srand(time((long *) 0));
528
529     /* 15 PRINT "INSTRUCTIONS (Y-N)";                                   */
530     /* 20 INPUT I$                                                      */
531     c = getlet("INSTRUCTIONS (Y-N)");
532
533     /* 25 IF I$="N" THEN 35                                             */
534     /* 30 GOSUB 375                                                     */
535     /* 35 GOTO 80                                                       */
536     if (c == 'Y')
537         print_instructions();
538
539     /* 150 REM *** LOCATE L ARRAY ITEMS ***                             */
540     /* 155 REM *** 1-YOU, 2-WUMPUS, 3&4-PITS, 5&6-BATS ***              */
541     /* 160 DIM L(6)                                                     */
542     /* 165 DIM M(6)                                                     */
543 badlocs:
544     /* 170 FOR J=1 TO 6                                                 */
545     /* 175 L(J)=FNA(0)                                                  */
546     /* 180 M(J)=L(J)                                                    */
547     /* 185 NEXT J                                                       */
548     for (j = 0; j < LOCS; j++)
549         loc[j] = save[j] = FNA();
550
551     /* 190 REM *** CHECK FOR CROSSOVERS (IE L(1)=L(2), ETC) ***         */
552     /* 195 FOR J=1 TO 6                                                 */
553     /* 200 FOR K=1 TO 6                                                 */
554     /* 205 IF J=K THEN 215                                              */
555     /* 210 IF L(J)=L(K) THEN 170                                        */
556     /* 215 NEXT K                                                       */
557     /* 220 NEXT J                                                       */
558     for (j = 0; j < LOCS; j++)
559         for (k = 0; k < LOCS; k++)
560             if (j == k)
561                 continue;
562             else if (loc[j] == loc[k])
563                 goto badlocs;
564
565     /* 225 REM *** SET NO. OF ARROWS ***                                */
566 newgame:    
567     /* 230 A=5                                                          */
568     /* 235 L=L(1)                                                       */
569     arrows = 5;
570     scratchloc = loc[YOU];
571
572     /* 240 REM *** RUN THE GAME ***                                     */
573     /* 245 PRINT "HUNT THE WUMPUS"                                      */
574     (void) puts("HUNT THE WUMPUS");
575
576 #ifdef DEBUG
577     (void) printf("Wumpus is at %d, pits at %d & %d, bats at %d & %d\n",
578                   loc[WUMPUS]+1,
579                   loc[PIT1]+1, loc[PIT2]+1,
580                   loc[BATS1]+1, loc[BATS2]+1);
581 #endif
582
583 nextmove:    
584     /* 250 REM *** HAZARD WARNING AND LOCATION ***                      */
585     /* 255 GOSUB 585                                                    */
586     check_hazards();
587
588     /* 260 REM *** MOVE OR SHOOT ***                                    */
589     /* 265 GOSUB 670                                                    */
590     /* 270 ON O GOTO 280,300                                            */
591     if (move_or_shoot())
592     {
593         /* 275 REM *** SHOOT ***                                        */
594         /* 280 GOSUB 715                                                */
595         shoot();
596
597         /* 285 IF F=0 THEN 255                                          */
598         if (finished == NOT)
599             goto nextmove;
600
601         /* 290 GOTO 310                                                 */
602     }
603     else
604     {
605         /* 295 REM *** MOVE ***                                         */
606         /* 300 GOSUB 975                                                */
607         move();
608
609         /* 305 IF F=0 THEN 255                                          */
610         if (finished == NOT)
611             goto nextmove;
612     }
613
614     /* 310 IF F>0 THEN 335                                              */
615     if (finished == LOSE)
616     {
617         /* 315 REM *** LOSE ***                                         */
618         /* 320 PRINT "HA HA HA - YOU LOSE!"                             */
619         /* 325 GOTO 340                                                 */
620         (void) puts("HA HA HA - YOU LOSE!");
621     }
622     else
623     {
624         /* 330 REM *** WIN ***                                          */
625         /* 335 PRINT "HEE HEE HEE - THE WUMPUS'LL GET YOU NEXT TIME!!"  */
626         (void) puts("HEE HEE HEE - THE WUMPUS'LL GET YOU NEXT TIME!!");
627     }
628
629     /* 340 FOR J=1 TO 6                                                 */
630     /* 345 L(J)=M(J)                                                    */
631     /* 350 NEXT J                                                       */
632     for (j = YOU; j < LOCS; j++)
633         loc[j] = save[j];
634
635     /* 355 PRINT "SAME SETUP (Y-N)";                                    */
636     /* 360 INPUT I$                                                     */
637     c = getlet("SAME SETUP (Y-N)");
638
639     /* 365 IF I$<>"Y"THEN 170                                           */
640     /* 370 GOTO 230                                                     */
641     if (c != 'Y')
642         goto badlocs;
643     else
644         goto newgame;
645 }
646
647 /* wumpus.c ends here */