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