Add test for urn actions.
[open-adventure.git] / main.c
diff --git a/main.c b/main.c
index d11575613113e186e3b5eb37e5f99cd040f8bdf8..5a3f2002683de89e3c78aad525adb756b0a447a0 100644 (file)
--- a/main.c
+++ b/main.c
@@ -8,7 +8,7 @@
  * 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
+ * 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.
@@ -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;
@@ -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. */
 {
@@ -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. */
@@ -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.
@@ -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;