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