Create a cheater to test strange save/resume cases.
authorEric S. Raymond <esr@thyrsus.com>
Mon, 26 Jun 2017 19:03:37 +0000 (15:03 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 26 Jun 2017 19:07:09 +0000 (15:07 -0400)
Patch due to Aaron Traas, but needed modification because of code
drift since submission.

.gitignore
.gitlab-ci.yml
Makefile
advent.h
cheat.c [new file with mode: 0644]
newdungeon.py
saveresume.c
tests/Makefile
tests/cheatresume.chk [new file with mode: 0644]
tests/cheatresume.log [new file with mode: 0644]

index 1e3ef437dd555ac6a824072d9ff8474f23903bad..123e27f6c92e66c69ae70de6e751233eb7e1479e 100644 (file)
@@ -12,3 +12,4 @@ MANIFEST
 .*~
 newdb.h
 newdb.c
+cheat
\ No newline at end of file
index 93f0af1775258e8d8d43fbdc189fb45cdf7a07db..45531263d9cdfcb3988661d9d6e31b5fa160a9a7 100644 (file)
@@ -21,6 +21,7 @@ binary:debug:
   artifacts:
     paths:
       - advent
+      - cheat
       - "*.gcda"
       - "*.gcno"
   # cache outputs to reduce the build time
@@ -35,10 +36,11 @@ binary:release:
     - apk add make gcc musl-dev python3
     - pip3 install PyYAML
   script: 
-    - make advent
+    - make advent cheat
   artifacts:
     paths:
       - advent
+      - cheat
   # cache outputs to reduce the build time
   cache:
     paths:
index 9021f686d11ef7980b01c18c29a42aa8cc722c9c..a435d0780a90a1cc3f556888745d8699d5356a23 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,7 @@ ifeq ($(UNAME_S),Linux)
 endif
 
 OBJS=main.o init.o actions.o score.o misc.o saveresume.o common.o
+CHEAT_OBJS=cheat.o init.o actions.o score.o misc.o saveresume.o common.o
 SOURCES=$(OBJS:.o=.c) dungeon.c advent.h common.h adventure.text Makefile control linenoise/linenoise.[ch] newdungeon.py
 
 .c.o:
@@ -55,6 +56,8 @@ score.o:      advent.h database.h common.h newdb.h
 
 misc.o:                advent.h database.h common.h newdb.h
 
+cheat.o:       advent.h database.h common.h newdb.h
+
 saveresume.o:  advent.h database.h common.h newdb.h
 
 common.o:      common.h
@@ -84,7 +87,11 @@ clean:
        rm -f .*~
        cd tests; $(MAKE) --quiet clean
 
-check: advent
+
+cheat: $(CHEAT_OBJS) linenoise.o newdb.o 
+       $(CC) $(CCFLAGS) $(DBX) -o cheat $(CHEAT_OBJS) linenoise.o newdb.o $(LDFLAGS) $(LIBS)
+
+check: advent cheat
        cd tests; $(MAKE) --quiet
 
 .SUFFIXES: .adoc .html .6
@@ -144,3 +151,4 @@ linty: advent
 
 debug: CCFLAGS += -O0 --coverage -ggdb
 debug: linty
+debug: cheat
index 4447b67a18563b644ef71e885c8023191d733710..754ea1646d419a34172849732052ddfafb9fbf7b 100644 (file)
--- a/advent.h
+++ b/advent.h
@@ -127,6 +127,7 @@ extern unsigned long get_next_lcg_value(void);
 extern long randrange(long);
 extern long score(enum termination);
 extern void terminate(enum termination) __attribute__((noreturn));
+extern int savefile(FILE *);
 extern int suspend(void);
 extern int resume(void);
 extern int restore(FILE *);
diff --git a/cheat.c b/cheat.c
new file mode 100644 (file)
index 0000000..9e23911
--- /dev/null
+++ b/cheat.c
@@ -0,0 +1,64 @@
+#define DEFINE_GLOBALS_FROM_INCLUDES
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <time.h>
+#include "advent.h"
+#include "database.h"
+#include "linenoise/linenoise.h"
+#include "newdb.h"
+
+struct game_t game;
+
+long LNLENG, LNPOSN;
+char rawbuf[LINESIZE], INLINE[LINESIZE + 1];
+
+long AMBER, AXE, BACK, BATTERY, BEAR, BIRD, BLOOD,
+     BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST,
+     CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS,
+     EMERALD, ENTER, ENTRNC, FIND, FISSURE, FOOD,
+     GRATE, HINT, INVENT, JADE, KEYS,
+     KNIFE, LAMP, LOCK, LOOK, MAGAZINE,
+     MESSAG, MIRROR, NUGGET, NUL, OGRE, OIL, OYSTER,
+     PEARL, PILLOW, PLANT, PLANT2, PYRAMID, RESER, ROD, ROD2,
+     RUBY, RUG, SAPPH, SAY, SIGN, SNAKE,
+     STEPS, STREAM, THROW, TRIDENT, TROLL, TROLL2,
+     URN, VASE, VEND, VOLCANO, WATER;
+
+FILE  *logfp = NULL, *rfp = NULL;
+bool oldstyle = false;
+bool editline = true;
+bool prompt = true;
+
+int main(int argc, char *argv[])
+{
+    FILE *fp = NULL;
+
+    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();
+
+    game.zzword = rndvoc(3, 0);
+    game.newloc = LOC_START;
+    game.loc = LOC_START;
+    game.limit = GAMELIMIT;
+    game.numdie = -1000;
+    game.saved = 1;
+    
+    fp = fopen("cheat_numdie.adv", WRITE_MODE);
+    if (fp == NULL)
+    {
+        printf("Can't open file. Exiting.\n");
+        exit(0);
+    }        
+
+    savefile(fp);
+    printf("cheat: tests/cheat_numdie.adv created.\n");
+    return 0;
+}
index e5169219404fe06992ca82ff0e4fa225e01d1178..bbfc0c8589e99ea3811e81dceae48bcfaaf7e84e 100755 (executable)
@@ -442,7 +442,7 @@ if __name__ == "__main__":
         len(db["locations"])-1,
         len(db["objects"])-1,
         len(db["hints"]),
-        len(db["classes"]),
+        len(db["classes"])-1,
         len(db["obituaries"]),
         len(db["turn_thresholds"]),
         len(db["actspk"]),
index 338615844b24cf6a945c4271d82a3ee887d2abf7..3546378a5ae6d4e7e6ae44db7fb18b7e91beeb46 100644 (file)
@@ -27,6 +27,20 @@ struct save_t {
 };
 struct save_t save;
 
+int savefile(FILE *fp)
+    /* Save game to file. No input or output from user. */
+{
+    long i, k;
+    datime(&i, &k);
+    k = i + 650 * k;
+    save.savetime = k;
+    save.mode = -1;
+    save.version = VRSION;
+    memcpy(&save.game, &game, sizeof(struct game_t));
+    IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp));
+    return(0);
+}
+
 /* Suspend and resume */
 int suspend(void)
 {
@@ -38,7 +52,6 @@ int suspend(void)
 #ifdef ADVENT_NOSAVE
     return GO_UNKNOWN;
 #endif
-    long i, k;
     FILE *fp = NULL;
 
     rspeak(SUSPEND_WARNING);
@@ -55,12 +68,7 @@ int suspend(void)
         linenoiseFree(name);
     }
 
-    datime(&i, &k);
-    k = i + 650 * k;
-    save.savetime = k;
-    save.mode = -1;
-    save.version = VRSION;
-    memcpy(&save.game, &game, sizeof(struct game_t));
+    savefile(fp);
     IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp));
     fclose(fp);
     rspeak(RESUME_HELP);
index cffab9a73391d093f3beb58bff8319936b1e45e4..412ec6ab7aa0cc3436bc4b433a38fe50c784f25a 100644 (file)
@@ -37,6 +37,8 @@ buildregress:
        done; \
        rm -f scratch.tmp
 regress:
+       $(ECHO) -n "Generate cheat file: "
+       ../cheat
        @for file in $(TESTLOADS); do \
            $(ECHO) -n "  $${file} "; grep '##' $${file}.log  || echo ' ## (no description)'; \
            OPTS=`sed -n /#options:/s///p <$${file}.log`; \
diff --git a/tests/cheatresume.chk b/tests/cheatresume.chk
new file mode 100644 (file)
index 0000000..8901e8b
--- /dev/null
@@ -0,0 +1,24 @@
+
+Welcome to Adventure!!  Would you like instructions?
+
+> n
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+> resume
+
+You are standing at the end of a road before a small brick building.
+Around you is a forest.  A small stream flows out of the building and
+down a gully.
+
+
+Now let's see you do it without suspending in mid-Adventure.
+
+You scored 10031 out of a possible 430, using 0 turn.
+
+You just went off my scale!!
+
+To achieve the next higher rating would be a neat trick!
+Congratulations!!
diff --git a/tests/cheatresume.log b/tests/cheatresume.log
new file mode 100644 (file)
index 0000000..e820ba0
--- /dev/null
@@ -0,0 +1,4 @@
+## Resume from absurd save file with numdie = -1000
+n
+resume
+cheat_numdie.adv