Refactor scoring so score() does not conditionally exit.
authorEric S. Raymond <esr@thyrsus.com>
Sun, 18 Jun 2017 16:51:05 +0000 (12:51 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Sun, 18 Jun 2017 16:51:05 +0000 (12:51 -0400)
actions.c
advent.h
main.c
score.c

index cbf73f27417b1535dac27c6558ba7a73fea17bdb..1938d24be054ce6c904e8d0d7247013f23e39c70 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -176,7 +176,7 @@ static void blast(void)
         if (HERE(ROD2))
             game.bonus = SPLATTER_MESSAGE;
         RSPEAK(game.bonus);
-        score(endgame);
+        terminate(endgame);
     }
 }
 
@@ -793,7 +793,7 @@ static int quit(FILE *input)
 /*  Quit.  Intransitive only.  Verify intent and exit if that's what he wants. */
 {
     if (YES(input, REALLY_QUIT, OK_MAN, OK_MAN))
-        score(quitgame);
+        terminate(quitgame);
     return GO_CLEAROBJ;
 }
 
@@ -950,13 +950,6 @@ static int throw (FILE *cmdin, long verb, token_t obj)
     return throw_support((++game.dkill == 1) ? DWARF_SMOKE : KILLED_DWARF);
 }
 
-static int vscore(void)
-/* Score.  Call scoring routine but tell it to return. */
-{
-    score(scoregame);
-    return GO_CLEAROBJ;
-}
-
 static int wake(token_t verb, token_t obj)
 /* Wake.  Only use is to disturb the dwarves. */
 {
@@ -1120,7 +1113,8 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
                 blast();
                 return GO_CLEAROBJ;
             case 23: /* SCOR  */
-                return vscore();
+               score(scoregame);
+               return GO_CLEAROBJ;
             case 24: /* FOO   */
                 return bigwords(WD1);
             case 25: /* BRIEF */
index c13a9052a5c72373dd9706e526071562389f0b1e..043dd6bb66cdd743c636e6b256eb9fe8e0eab0ac 100644 (file)
--- a/advent.h
+++ b/advent.h
@@ -114,7 +114,8 @@ enum termination {endgame, quitgame, scoregame};
 extern void set_seed(long);
 extern unsigned long get_next_lcg_value(void);
 extern long randrange(long);
-extern void score(enum termination);
+extern long score(enum termination);
+extern void terminate(enum termination) __attribute__((noreturn));
 extern int suspend(FILE *);
 extern int resume(FILE *);
 extern int restore(FILE *);
diff --git a/main.c b/main.c
index c2e73a0c5281bc9ae877d24749c07f442c39f435..6eb783ac46a1b715a4bb17f293e6bf74bc41d150 100644 (file)
--- a/main.c
+++ b/main.c
@@ -150,7 +150,7 @@ int main(int argc, char *argv[])
             break;
     }
     /* show score and exit */
-    score(quitgame);
+    terminate(quitgame);
 }
 
 static bool fallback_handler(char *buf)
@@ -482,12 +482,11 @@ static void croak(FILE *cmdin)
         /*  He died during closing time.  No resurrection.  Tally up a
          *  death and exit. */
         RSPEAK(DEATH_CLOSING);
-        score(endgame);
-
+        terminate(endgame);
     }
     /* FIXME: Arithmetic on message numbers */
     else if (game.numdie == MAXDIE || !YES(cmdin, WATCH_IT + game.numdie * 2, WHICH_WAY + game.numdie * 2, OK_MAN))
-        score(endgame);
+        terminate(endgame);
     else {
         game.place[WATER] = game.place[OIL] = NOWHERE;
         if (TOTING(LAMP))
@@ -1121,8 +1120,7 @@ Laction:
         case GO_DWARFWAKE:
             /*  Oh dear, he's disturbed the dwarves. */
             RSPEAK(DWARVES_AWAKEN);
-            score(endgame);
-            return true;
+            terminate(endgame);
         default:
             BUG(99);
         }
diff --git a/score.c b/score.c
index c0f28faa2c8d1f075f2a3250daabf61f18a719bf..abe333705ebde9615663d03de945eb60f1de43f0 100644 (file)
--- a/score.c
+++ b/score.c
@@ -7,11 +7,13 @@
  * scoring and wrap-up
  */
 
-void score(enum termination mode)
+static long mxscor;    /* ugh..the price for having score() not exit. */
+
+long score(enum termination mode)
 /* mode is 'scoregame' if scoring, 'quitgame' if quitting, 'endgame' if died
  * or won */
 {
-    long score = 0, mxscor = 0;
+    long score = 0;
 
     /*  The present scoring algorithm is as follows:
      *     Objective:          Points:        Present total possible:
@@ -34,6 +36,7 @@ void score(enum termination mode)
 
     /*  First tally up the treasures.  Must be in building and not broken.
      *  Give the poor guy 2 points just for finding each treasure. */
+    mxscor = 0;
     for (long i = MINTRS; i <= MAXTRS; i++) {
         if (object_descriptions[i].inventory != 0) {
             long k = 12;
@@ -99,21 +102,27 @@ void score(enum termination mode)
         SETPRM(1, score, mxscor);
         SETPRM(3, game.turns, game.turns);
         RSPEAK(GARNERED_POINTS);
-        return;
     }
 
-    /* that should be good enough.  Let's tell him all about it. */
-    if (score + game.trnluz + 1 >= mxscor && game.trnluz != 0)
+    return score;
+}
+
+void terminate(enum termination mode)
+/* End of game.  Let's tell him all about it. */
+{
+    long points = score(mode);
+
+    if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0)
         RSPEAK(TOOK_LONG);
-    if (score + game.saved + 1 >= mxscor && game.saved != 0)
+    if (points + game.saved + 1 >= mxscor && game.saved != 0)
         RSPEAK(WITHOUT_SUSPENDS);
-    SETPRM(1, score, mxscor);
+    SETPRM(1, points, mxscor);
     SETPRM(3, game.turns, game.turns);
     RSPEAK(TOTAL_SCORE);
     for (long i = 1; i <= (long)CLSSES; i++) {
-        if (CVAL[i] >= score) {
+        if (CVAL[i] >= points) {
             newspeak(class_messages[i]);
-            i = CVAL[i] + 1 - score;
+            i = CVAL[i] + 1 - points;
             SETPRM(1, i, i);
             RSPEAK(NEXT_HIGHER);
             exit(0);
@@ -122,5 +131,6 @@ void score(enum termination mode)
     RSPEAK(OFF_SCALE);
     RSPEAK(NO_HIGHER);
     exit(0);
-
 }
+
+/* end */