Makere magic numbers for cond bits into symbols.
[open-adventure.git] / main.c
diff --git a/main.c b/main.c
index 95e69732457947eaa61cb891c1068b5cd3f0e4c1..1f866d81b28bae49d541431a0376d6a1cb3e9571 100644 (file)
--- a/main.c
+++ b/main.c
@@ -3,15 +3,15 @@
  *
  * The author - Don Woods - apologises for the style of the code; it
  * is a result of running the original Fortran IV source through a
- * home-brew Fortran-to-C converter.)
+ * home-brew Fortran-to-C converter.
  *
  * Now that the code has been restructured into something much closer
  * to idiomatic C, the following is more appropriate:
  *
- * ESR apologizes for the remaing gotos (now confined to two functions
- * in this file - there used to be hundreds of them, *everywhere*),
- * and the offensive globals.  Applying the Structured Program Theorem
- * can be hard.
+ * ESR apologizes for the remaing gotos (now confined to one function
+ * in this file - there used to be over 350 of them, *everywhere*),
+ * and for the offensive globals.  Applying the Structured Program
+ * Theorem can be hard.
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -122,20 +122,9 @@ int main(int argc, char *argv[])
     set_seed(seedval);
 
     /*  Initialize game variables */
-    if (!game.setup)
-       initialise();
-
-    /*  Unlike earlier versions, adventure is no longer restartable.  (This
-     *  lets us get away with modifying things such as OBJSND(BIRD) without
-     *  having to be able to undo the changes later.)  If a "used" copy is
-     *  rerun, we come here and tell the player to run a fresh copy. */
-    if (game.setup <= 0) {
-       RSPEAK(201);
-       exit(0);
-    }
+    initialise();
 
     /*  Start-up, dwarf stuff */
-    game.setup= -1;
     game.zzword=RNDVOC(3,0);
     game.novice=YES(stdin, 65,1,0);
     game.newloc=1;
@@ -146,7 +135,7 @@ int main(int argc, char *argv[])
     if (logfp)
        fprintf(logfp, "seed %ld\n", seedval);
 
-    /* interpret commands ubtil EOF or interrupt */
+    /* interpret commands until EOF or interrupt */
     for (;;) {
        if (!do_command(stdin))
            break;
@@ -182,7 +171,7 @@ static void checkhints(FILE *cmdin)
        for (int hint=1; hint<=HNTMAX; hint++) {
            if (game.hinted[hint])
                continue;
-           if (!CNDBIT(game.loc,hint+10))
+           if (!CNDBIT(game.loc,hint+HBASE))
                game.hintlc[hint]= -1;
            ++game.hintlc[hint];
            /*  Come here if he's been long enough at required loc(s) for some
@@ -267,6 +256,65 @@ static void checkhints(FILE *cmdin)
     }
 }
 
+bool spotted_by_pirate(int i)
+{
+    if (i != PIRATE) 
+       return false;
+
+    /*  The pirate's spotted him.  He leaves him alone once we've
+     *  found chest.  K counts if a treasure is here.  If not, and
+     *  tally=1 for an unseen chest, let the pirate be spotted.
+     *  Note that game.place[CHEST]=0 might mean that he's thrown
+     *  it to the troll, but in that case he's seen the chest
+     *  (game.prop=0). */
+    if (game.loc == game.chloc || game.prop[CHEST] >= 0)
+       return true;
+    int k=0;
+    for (int j=MINTRS; j<=MAXTRS; j++) {
+       /*  Pirate won't take pyramid from plover room or dark
+        *  room (too easy!). */
+       if (j==PYRAM && (game.loc==PLAC[PYRAM] || game.loc==PLAC[EMRALD])) {
+           return true;
+       }
+       if (TOTING(j)) {
+           if (game.place[CHEST] == 0) {
+               /*  Install chest only once, to insure it is
+                *  the last treasure in the list. */
+               MOVE(CHEST,game.chloc);
+               MOVE(MESSAG,game.chloc2);
+           }
+           RSPEAK(128);
+           for (int j=MINTRS; j<=MAXTRS; j++) {
+               if (!(j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) {
+                   if (AT(j) && game.fixed[j] == 0)
+                       CARRY(j,game.loc);
+                   if (TOTING(j))
+                       DROP(j,game.chloc);
+               }
+           }
+           game.dloc[PIRATE]=game.chloc;
+           game.odloc[PIRATE]=game.chloc;
+           game.dseen[PIRATE]=false;
+           return true;
+       }
+       if (HERE(j))
+           k=1;
+    }
+    /* Force chest placement before player finds last treasure */
+    if (game.tally == 1 && k == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) {
+       RSPEAK(186);
+       MOVE(CHEST,game.chloc);
+       MOVE(MESSAG,game.chloc2);
+       game.dloc[PIRATE]=game.chloc;
+       game.odloc[PIRATE]=game.chloc;
+       game.dseen[PIRATE]=false;
+       return true;
+    }
+    if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20))
+       RSPEAK(127);
+    return true;
+}
+
 static bool dwarfmove(void)
 /* Dwarves move.  Return true if player survives, false if he dies. */
 {
@@ -286,7 +334,7 @@ static bool dwarfmove(void)
      *  means dwarves won't follow him into dead end in maze, but
      *  c'est la vie.  They'll wait for him outside the dead
      *  end. */
-    if (game.loc == 0 || FORCED(game.loc) || CNDBIT(game.newloc,3))
+    if (game.loc == 0 || FORCED(game.loc) || CNDBIT(game.newloc,NOARRR))
        return true;
 
     /* Dwarf activity level ratchets up */
@@ -300,7 +348,7 @@ static bool dwarfmove(void)
      *  the 5 dwarves.  If any of the survivors is at loc,
      *  replace him with the alternate. */
     if (game.dflag == 1) {
-       if (!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc,4) || PCT(85))))
+       if (!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc,NOBACK) || PCT(85))))
            return true;
        game.dflag=2;
        for (int i=1; i<=2; i++) {
@@ -328,7 +376,6 @@ static bool dwarfmove(void)
     attack=0;
     stick=0;
     for (int i=1; i<=NDWARVES; i++) {
-       int k;
        if (game.dloc[i] == 0)
            continue;
        /*  Fill TK array with all the places this dwarf might go. */
@@ -345,7 +392,7 @@ static bool dwarfmove(void)
                                j >= 20 ||
                                game.newloc == game.dloc[i] ||
                                FORCED(game.newloc) ||
-                               (i == PIRATE && CNDBIT(game.newloc,3)) ||
+                               (i == PIRATE && CNDBIT(game.newloc,NOARRR)) ||
                                labs(TRAVEL[kk])/1000000 == 100);
                if (!avoided) {
                    TK[j++] = game.newloc;
@@ -362,67 +409,8 @@ static bool dwarfmove(void)
        game.dseen[i]=(game.dseen[i] && INDEEP(game.loc)) || (game.dloc[i] == game.loc || game.odloc[i] == game.loc);
        if (!game.dseen[i]) continue;
        game.dloc[i]=game.loc;
-       if (i == PIRATE) {
-           /*  The pirate's spotted him.  He leaves him alone once we've
-            *  found chest.  K counts if a treasure is here.  If not, and
-            *  tally=1 for an unseen chest, let the pirate be spotted.
-            *  Note that game.place(CHEST)=0 might mean that he's thrown
-            *  it to the troll, but in that case he's seen the chest
-            *  (game.prop=0). */
-           if (game.loc == game.chloc || game.prop[CHEST] >= 0)
-               continue;
-           k=0;
-           for (int j=MINTRS; j<=MAXTRS; j++) {
-               /*  Pirate won't take pyramid from plover room or dark
-                *  room (too easy!). */
-               if (j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD])) {
-                   if (HERE(j))
-                       k=1;
-                   continue;
-               }
-               if (TOTING(j)) {
-                   if (game.place[CHEST] == 0) {
-                       /*  Install chest only once, to insure it is
-                        *  the last treasure in the list. */
-                       MOVE(CHEST,game.chloc);
-                       MOVE(MESSAG,game.chloc2);
-                   }
-                   RSPEAK(128);
-                   for (int j=MINTRS; j<=MAXTRS; j++) {
-                       if (!(j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) {
-                           if (AT(j) && game.fixed[j] == 0)
-                               CARRY(j,game.loc);
-                           if (TOTING(j))
-                               DROP(j,game.chloc);
-                       }
-                   }
-                   game.dloc[PIRATE]=game.chloc;
-                   game.odloc[PIRATE]=game.chloc;
-                   game.dseen[PIRATE]=false;
-                   /* C doesn't have what the Structured rogramming
-                    * Theorem says we need here - multi-level loop
-                    * breakout. We simulate with a goto. Irreducible, alas.
-                    */
-                   goto jumpout;
-               }
-               if (HERE(j))
-                   k=1;
-           }
-           /* Force chest placement before player finds last treasure */
-           if (game.tally == 1 && k == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) {
-               RSPEAK(186);
-               MOVE(CHEST,game.chloc);
-               MOVE(MESSAG,game.chloc2);
-               game.dloc[PIRATE]=game.chloc;
-               game.odloc[PIRATE]=game.chloc;
-               game.dseen[PIRATE]=false;
-               continue;
-           }
-           if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20))
-               RSPEAK(127);
+       if (spotted_by_pirate(i))
            continue;
-       }
-
        /* This threatening little dwarf is in the room with him! */
        ++game.dtotal;
        if (game.odloc[i] == game.dloc[i]) {
@@ -432,7 +420,6 @@ static bool dwarfmove(void)
            if (randrange(1000) < 95*(game.dflag-2))
                ++stick;
        }
-    jumpout:;
     }
 
     /*  Now we know what's happening.  Let's tell the poor sucker about it.
@@ -537,7 +524,7 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
        game.oldloc=game.loc;
        K2=0;
        if (motion == game.loc)K2=91;
-       if (CNDBIT(game.loc,4))K2=274;
+       if (CNDBIT(game.loc,NOBACK))K2=274;
        if (K2 == 0) {
            for (;;) {
                LL=MOD((labs(TRAVEL[KK])/1000),1000);
@@ -914,7 +901,7 @@ static void listobjects(void)
 static bool do_command(FILE *cmdin)
 /* Get and execute a command */ 
 {
-    long KQ, VERB, KK, V1, V2;
+    long KQ, VERB, V1, V2;
     long i, k, KMOD;
     static long igo = 0;
     static long obj = 0;
@@ -932,7 +919,7 @@ static bool do_command(FILE *cmdin)
      *  wants to go.  If so, the dwarf's blocking his way.  If
      *  coming from place forbidden to pirate (dwarves rooted in
      *  place) let him get out (and attacked). */
-    if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc,3)) {
+    if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc,NOARRR)) {
        for (i=1; i<=NDWARVES-1; i++) {
            if (game.odloc[i] == game.newloc && game.dseen[i]) {
                game.newloc=game.loc;
@@ -1026,15 +1013,12 @@ static bool do_command(FILE *cmdin)
            part=transitive;
            goto Laction;
        }
-       if (closecheck())
+       if (closecheck()) {
            if (game.closed)
                return true;
-           else
-               goto L19999;
-
-       lampcheck();
+       } else
+           lampcheck();
 
-    L19999:
        k=43;
        if (LIQLOC(game.loc) == WATER)k=70;
        V1=VOCAB(WD1,-1);