Encapsulate object-state state tests and setttings in macros.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 7 Apr 2023 20:11:04 +0000 (16:11 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Sat, 8 Apr 2023 23:35:41 +0000 (19:35 -0400)
This isn't a complete refwctoring, just the part than can be done with
transparetly correct capture of inlinre logic into macros.

No logic changes. Tests pass, 100% coverage.

actions.c
advent.h
init.c
main.c
misc.c
saveresume.c
score.c

index 20f0b9041bcd7bae6d3af99ff715e542c90c3495..cbc8d3ff59b1ee6d0f45066d75182f4286ef489c 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -244,7 +244,7 @@ static phase_codes_t bigwords(vocab_t id)
 static void blast(void)
 /*  Blast.  No effect unless you've got dynamite, which is a neat trick! */
 {
-    if (game.objects[ROD2].prop == STATE_NOTFOUND || !game.closed)
+    if (PROP_IS_NOTFOUND(ROD2) || !game.closed)
         rspeak(REQUIRES_DYNAMITE);
     else {
         if (HERE(ROD2)) {
@@ -376,7 +376,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
 
     }
 
-    if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && STASHED(BIRD) != BIRD_CAGED) {
+    if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && !PROP_IS_STASHED(BIRD)) {
         if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) {
             DESTROY(BIRD);
             rspeak(BIRD_CRAP);
@@ -393,7 +393,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
         game.objects[BIRD].prop = BIRD_CAGED;
     }
     if ((obj == BIRD || obj == CAGE) &&
-        (game.objects[BIRD].prop == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) {
+        (game.objects[BIRD].prop == BIRD_CAGED || PROP_STASHED(BIRD) == BIRD_CAGED)) {
         /* expression maps BIRD to CAGE and CAGE to BIRD */
         carry(BIRD + CAGE - obj, game.loc);
     }
@@ -403,8 +403,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj)
     if (obj == BOTTLE && LIQUID() != NO_OBJECT)
         game.objects[LIQUID()].place = CARRIED;
 
-    if (GSTONE(obj) && game.objects[obj].prop != STATE_FOUND) {
-        game.objects[obj].prop = STATE_FOUND;
+    if (GSTONE(obj) && !PROP_IS_FOUND(obj)) {
+        PROP_SET_FOUND(obj);
         game.objects[CAVITY].prop = CAVITY_EMPTY;
     }
     rspeak(OK_MAN);
@@ -936,7 +936,7 @@ static phase_codes_t listen(void)
         soundlatch = true;
     }
     for (obj_t i = 1; i <= NOBJECTS; i++) {
-        if (!HERE(i) || objects[i].sounds[0] == NULL || game.objects[i].prop < 0)
+        if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i))
             continue;
         int mi =  game.objects[i].prop;
         /* (ESR) Some unpleasant magic on object states here. Ideally
@@ -1116,8 +1116,7 @@ static phase_codes_t read(command_t command)
         } else {
             pspeak(OYSTER, hear, true, 1);     // Not really a sound, but oh well.
         }
-    } else if (objects[command.obj].texts[0] == NULL ||
-               game.objects[command.obj].prop == STATE_NOTFOUND) {
+    } else if (objects[command.obj].texts[0] == NULL || PROP_IS_NOTFOUND(command.obj)) {
         speak(actions[command.verb].message);
     } else
         pspeak(command.obj, study, true, game.objects[command.obj].prop);
@@ -1297,9 +1296,9 @@ static phase_codes_t wave(verb_t verb, obj_t obj)
     }
 
     if (game.objects[BIRD].prop == BIRD_UNCAGED && game.loc == game.objects[STEPS].place
-       && game.objects[JADE].prop == STATE_NOTFOUND) {
+       && PROP_IS_NOTFOUND(JADE)) {
         drop(JADE, game.loc);
-        game.objects[JADE].prop = STATE_FOUND;
+        PROP_SET_FOUND(JADE);
         --game.tally;
         rspeak(NECKLACE_FLY);
         return GO_CLEAROBJ;
index 55d1b82ffd250eea35c80ae184c4c48dc2f40142..738d546c617633712b57d3bbc8a2255a41a218cd 100644 (file)
--- a/advent.h
+++ b/advent.h
 #define IS_FIXED -1
 #define IS_FREE 0
 
-/* Map a state property value to a negative range, where the object cannot be
+/* STASH map a state property value to a negative range, where the object cannot be
  * picked up but the value can be recovered later.  Avoid colliding with -1,
  * which has its own meaning as STATE_NOTFOUND. */
-#define STASHED(obj)   (-1 - game.objects[obj].prop)
+#define PROP_STASHED(obj)      (STATE_NOTFOUND - game.objects[obj].prop)
+#define PROP_IS_STASHED(obj)   (game.objects[obj].prop < STATE_NOTFOUND)
+#define PROP_IS_NOTFOUND(obj)  (game.objects[obj].prop == STATE_NOTFOUND)
+/* Don't use this on an object wi nore thab 2 (unstashed) states */ 
+#define PROP_IS_FOUND(obj)     (game.objects[obj].prop == STATE_FOUND)
+/* Magic number -2 allows a PROP_STASHED version of state 1 */
+#define PROP_IS_INVALID(val)   (val < -2 || val > 1)
+#define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0)
+#define PROP_SET_FOUND(obj)    (game.objects[obj].prop = STATE_FOUND)
+#define PROP_SET_NOT_FOUND(obj)        (game.objects[obj].prop = STATE_NOTFOUND)
 
 #define PROMPT "> "
 
diff --git a/init.c b/init.c
index c384f7106f84e685de34eb36ea91c5221daae591..0813fb7ce493764f052a5a5dab397830eb6aafa3 100644 (file)
--- a/init.c
+++ b/init.c
@@ -90,7 +90,7 @@ int initialise(void)
     for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
         if (objects[treasure].is_treasure) {
             if (objects[treasure].inventory != 0)
-                game.objects[treasure].prop = STATE_NOTFOUND;
+                PROP_SET_NOT_FOUND(treasure);
             game.tally = game.tally - game.objects[treasure].prop;
         }
     }
diff --git a/main.c b/main.c
index a740b42158bed8529e89e80256a9989dc77957aa..4b6165e4e5acf81fc1f27bb41a0aad0b7f897cbf 100644 (file)
--- a/main.c
+++ b/main.c
@@ -139,7 +139,7 @@ static void checkhints(void)
                     game.hints[hint].lc = 0;
                     return;
                 case 4:        /* dark */
-                    if (game.objects[EMERALD].prop != STATE_NOTFOUND && game.objects[PYRAMID].prop == STATE_NOTFOUND)
+                    if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID))
                         break;
                     game.hints[hint].lc = 0;
                     return;
@@ -166,7 +166,7 @@ static void checkhints(void)
                         break;
                     return;
                 case 9:        /* jade */
-                    if (game.tally == 1 && game.objects[JADE].prop < 0)
+                    if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE))
                         break;
                     game.hints[hint].lc = 0;
                     return;
@@ -196,10 +196,10 @@ static bool spotted_by_pirate(int i)
     /*  The pirate's spotted him.  Pirate 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] = LOC_NOWHERE might mean that he's thrown
+     *  that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's thrown
      *  it to the troll, but in that case he's seen the chest
-     *  (game.prop[CHEST] == STATE_FOUND). */
-    if (game.loc == game.chloc || game.objects[CHEST].prop != STATE_NOTFOUND)
+     *  PROP_IS_FOUND(CHEST) == true. */
+    if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST))
         return true;
     int snarfed = 0;
     bool movechest = false, robplayer = false;
@@ -917,10 +917,10 @@ static void listobjects(void)
                 obj = obj - NOBJECTS;
             if (obj == STEPS && TOTING(NUGGET))
                 continue;
-            if (game.objects[obj].prop < 0) {
+            if (PROP_IS_STASHED_OR_UNSEEN(obj)) {
                 if (game.closed)
                     continue;
-                game.objects[obj].prop = STATE_FOUND;
+                PROP_SET_FOUND(obj);
                 if (obj == RUG)
                     game.objects[RUG].prop = RUG_DRAGON;
                 if (obj == CHAIN)
@@ -1102,7 +1102,7 @@ static bool do_command(void)
                     pspeak(OYSTER, look, true, 1);
                 for (size_t i = 1; i <= NOBJECTS; i++) {
                     if (TOTING(i) && game.objects[i].prop < 0)
-                        game.objects[i].prop = STASHED(i);
+                        game.objects[i].prop = PROP_STASHED(i);
                 }
             }
 
diff --git a/misc.c b/misc.c
index 88899410f38c457be553346a24d9f1dc796ff28d..f224d4ce15089d48d82389d210737f98772c3f2b 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -600,7 +600,7 @@ void put(obj_t object, loc_t where, int pval)
  *  negated game.prop values for the repository objects. */
 {
     move(object, where);
-    game.objects[object].prop = (-1) - pval;;  // Needs to stay synchronized with STASHED
+    game.objects[object].prop = (-1) - pval;;  // Needs to stay synchronized with PROP_STASHED
 }
 
 void carry(obj_t object, loc_t where)
index 4cac0343a2a41f7c7a59a573ba61caa44414cf30..ceda43c1671edb1dadffaedd81d9d0df99d74c9e 100644 (file)
@@ -229,8 +229,7 @@ bool is_valid(struct game_t valgame)
 
     /* Check that properties of objects aren't beyond expected */
     for (obj_t obj = 0; obj <= NOBJECTS; obj++) {
-       /* Magic number -2 allows a STASHED version of state 1 */
-        if (valgame.objects[obj].prop < -2 || valgame.objects[obj].prop > 1) {
+        if (PROP_IS_INVALID(valgame.objects[obj].prop)) {
             switch (obj) {
             case RUG:
             case DRAGON:
diff --git a/score.c b/score.c
index 2e804e4983741789f25190a076820df3e04088fd..ed9cdeda34263281610372603e9da659ff906979 100644 (file)
--- a/score.c
+++ b/score.c
@@ -50,7 +50,7 @@ int score(enum termination mode)
                 k = 16;
             if (game.objects[i].prop > STATE_NOTFOUND)
                 score += 2;
-            if (game.objects[i].place == LOC_BUILDING && game.objects[i].prop == STATE_FOUND)
+            if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i))
                 score += k - 2;
             mxscor += k;
         }