Move PRNG initialization to simplify cheat.c
[open-adventure.git] / main.c
diff --git a/main.c b/main.c
index 5cb4a87a939dafec2ac154d1af3b08d7ed6e3d36..077e3a996d200dde709fda3215035b194f5c9c99 100644 (file)
--- a/main.c
+++ b/main.c
  * and for the offensive globals.  Applying the Structured Program
  * Theorem can be hard.
  */
-#define DEFINE_GLOBALS_FROM_INCLUDES
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdbool.h>
 #include <getopt.h>
 #include <signal.h>
-#include <time.h>
 #include <string.h>
 #include "advent.h"
 #include "linenoise/linenoise.h"
 
 #define DIM(a) (sizeof(a)/sizeof(a[0]))
 
-struct game_t game;
-
-long LNLENG, LNPOSN;
-char rawbuf[LINESIZE], INLINE[LINESIZE + 1];
+struct game_t game = {
+    .dloc[1] = LOC_KINGHALL,
+    .dloc[2] = LOC_WESTBANK,
+    .dloc[3] = LOC_Y2,
+    .dloc[4] = LOC_ALIKE3,
+    .dloc[5] = LOC_COMPLEX,
+
+    /*  Sixth dwarf is special (the pirate).  He always starts at his
+     *  chest's eventual location inside the maze. This loc is saved
+     *  in chloc for ref. The dead end in the other maze has its
+     *  loc stored in chloc2. */
+    .dloc[6] = LOC_DEADEND12,
+    .chloc   = LOC_DEADEND12,
+    .chloc2  = LOC_DEADEND13,
+    .abbnum  = 5,
+    .clock1  = WARNTIME,
+    .clock2  = FLASHTIME,
+    .blklin  = true
+};
 
 FILE  *logfp = NULL, *rfp = NULL;
 bool oldstyle = false;
@@ -45,7 +59,7 @@ static void sig_handler(int signo)
         if (logfp != NULL)
             fflush(logfp);
     }
-    exit(0);
+    exit(EXIT_FAILURE);
 }
 // LCOV_EXCL_STOP
 
@@ -116,24 +130,15 @@ int main(int argc, char *argv[])
 #endif
             fprintf(stderr,
                     "        -s suppress command editing\n");
-            exit(-1);
+            exit(EXIT_FAILURE);
             break;
         }
     }
 
     linenoiseHistorySetMaxLen(350);
 
-    /* Initialize our LCG PRNG with parameters tested against
-     * Knuth vol. 2. by the original authors */
-    game.lcg_a = 1093;
-    game.lcg_c = 221587;
-    game.lcg_m = 1048576;
-    srand(time(NULL));
-    long seedval = (long)rand();
-    set_seed(seedval);
-
     /*  Initialize game variables */
-    initialise();
+    long seedval = initialise();
 
     /*  Start-up, dwarf stuff */
     make_zzword(game.zzword);
@@ -374,9 +379,12 @@ static bool dwarfmove(void)
             if (PCT(50))
                 game.dloc[j] = 0;
         }
+
+        /* Alternate initial loc for dwarf, in case one of them
+        *  starts out on top of the adventurer. */
         for (int i = 1; i <= NDWARVES - 1; i++) {
             if (game.dloc[i] == game.loc)
-                game.dloc[i] = DALTLC;
+                game.dloc[i] = DALTLC; //
             game.odloc[i] = game.dloc[i];
         }
         rspeak(DWARF_RAN);
@@ -521,7 +529,7 @@ static void croak(void)
  *  him, so we need game.oldlc2, which is the last place he was
  *  safe.) */
 
-static bool playermove(token_t verb, int motion)
+static bool playermove( int motion)
 {
     int scratchloc, travel_entry = tkey[game.loc];
     game.newloc = game.loc;
@@ -609,8 +617,6 @@ static bool playermove(token_t verb, int motion)
                 spk = UNSURE_FACING;
             if (motion == OUTSIDE || motion == INSIDE)
                 spk = NO_INOUT_HERE;
-            if (verb == FIND || verb == INVENTORY)
-                spk = NEARBY;
             if (motion == XYZZY || motion == PLUGH)
                 spk = NOTHING_HAPPENS;
             if (motion == CRAWL)
@@ -624,6 +630,7 @@ static bool playermove(token_t verb, int motion)
     /* (ESR) We've found a destination that goes with the motion verb.
      * Next we need to check any conditional(s) on this destination, and
      * possibly on following entries. */
+    /* FIXME: Magic numbers related to move opcodes */
     do {
         for (;;) { /* L12 loop */
             for (;;) {
@@ -706,8 +713,8 @@ static bool playermove(token_t verb, int motion)
                      * so step out and block him.  (standard travel
                      * entries check for game.prop(TROLL)=0.)  Special
                      * stuff for bear. */
-                    if (game.prop[TROLL] == 1) {
-                        pspeak(TROLL, look, 1);
+                    if (game.prop[TROLL] == TROLL_PAIDONCE) {
+                        pspeak(TROLL, look, TROLL_PAIDONCE);
                         game.prop[TROLL] = 0;
                         move(TROLL2, 0);
                         move(TROLL2 + NOBJECTS, 0);
@@ -718,13 +725,13 @@ static bool playermove(token_t verb, int motion)
                         return true;
                     } else {
                         game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc;
-                        if (game.prop[TROLL] == 0)
-                            game.prop[TROLL] = 1;
+                        if (game.prop[TROLL] == TROLL_UNPAID)
+                            game.prop[TROLL] = TROLL_PAIDONCE;
                         if (!TOTING(BEAR))
                             return true;
                         rspeak(BRIDGE_COLLAPSE);
-                        game.prop[CHASM] = 1;
-                        game.prop[TROLL] = 2;
+                        game.prop[CHASM] = BRIDGE_WRECKED;
+                        game.prop[TROLL] = TROLL_GONE;
                         drop(BEAR, game.newloc);
                         game.fixed[BEAR] = -1;
                         game.prop[BEAR] = BEAR_DEAD;
@@ -780,7 +787,7 @@ static bool closecheck(void)
      *  have been activated, since we've found chest. */
     if (game.clock1 == 0) {
         game.prop[GRATE] = GRATE_CLOSED;
-        game.prop[FISSURE] = 0;
+        game.prop[FISSURE] = UNBRIDGED;
         for (int i = 1; i <= NDWARVES; i++) {
             game.dseen[i] = false;
             game.dloc[i] = 0;
@@ -997,7 +1004,7 @@ static bool do_command()
             rspeak(TAME_BEAR);
         speak(msg);
         if (FORCED(game.loc)) {
-            if (playermove(command.verb, 1))
+            if (playermove(HERE))
                 return true;
             else
                 continue;      /* back to top of main interpreter loop */
@@ -1034,6 +1041,8 @@ L2600:
 
         /* This is where we get a new command from the user */
         char* input;
+        char inputbuf[LINESIZE];
+
         for (;;) {
             input = get_input();
             if (input == NULL)
@@ -1045,8 +1054,12 @@ L2600:
             if (strcmp(input, "") != 0)
                 break;
         }
+
+        strncpy(inputbuf, input, LINESIZE - 1);
+        linenoiseFree(input);
+
         long tokens[4];
-        tokenize(input, tokens);
+        tokenize(inputbuf, tokens);
         command.wd1 = tokens[0];
         command.wd1x = tokens[1];
         command.wd2 = tokens[2];
@@ -1099,7 +1112,7 @@ L2607:
             command.wd1x = command.wd2x;
             wordclear(&command.wd2);
         } else {
-            /* FIXME: Magic numbers */
+            /* FIXME: Magic numbers related to vocabulary */
             if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) ||
                   (V2 != 1000 + PLANT && V2 != 1000 + DOOR))) {
                 if (AT(V2 - 1000))
@@ -1123,15 +1136,16 @@ Lookup:
         defn = get_vocab_id(word1);
         if (defn == -1) {
             /* Gee, I don't understand. */
-            if (fallback_handler(input))
+            if (fallback_handler(inputbuf))
                 continue;
             rspeak(DONT_KNOW, command.wd1, command.wd1x);
             goto L2600;
         }
+        /* FIXME: magic numbers related to vocabulary */
         kmod = MOD(defn, 1000);
         switch (defn / 1000) {
         case 0:
-            if (playermove(command.verb, kmod))
+            if (playermove(kmod))
                 return true;
             else
                 continue;      /* back to top of main interpreter loop */
@@ -1155,7 +1169,7 @@ Laction:
         case GO_TERMINATE:
             return true;
         case GO_MOVE:
-            playermove(command.verb, NUL);
+            playermove(NUL);
             return true;
         case GO_TOP:
             continue;  /* back to top of main interpreter loop */
@@ -1186,7 +1200,6 @@ Laction:
         default:
             BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
         }
-        linenoiseFree(input);
     }
 }