From 12f909bcc9ffddade92fb1e310d67671c1470425 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 14 Mar 2023 08:03:24 -0400 Subject: [PATCH 01/23] Start advent430 branch for correctness testing. The purpose of this branch is to create a version of the game from before the bug fixes, refactoring, and logic changes. We want this so we can run it against our 100% coverage test suite and see all changes in behavior. This branch is forked from the point where the prompt and the oldstyle option were added. At this point there had been only two logic changes: 1. Do initialization of the LCG with gettimeofday(). Note that this change will not affectt regression testing, since the initialization done in this way will nbe overridden in the logs by seed commands. 2. Refactor the input routines to a normal Unixy organization. This is required for the -l option to work. This commit just builds the binary at advent430 where it won't collide with the production version. --- Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 68ffd5b..ae2abfa 100644 --- a/Makefile +++ b/Makefile @@ -4,10 +4,10 @@ OBJS=main.o init.o actions1.o actions2.o score.o misc.o SOURCES=$(OBJS:.o=.c) COPYING NEWS README TODO advent.text control .c.o: - gcc -O $(DBX) -c $< + gcc -g $(DBX) -c $< -advent: $(OBJS) - gcc -O $(DBX) -o advent $(OBJS) +advent430: $(OBJS) + gcc -g $(DBX) -o advent430 $(OBJS) main.o: misc.h funcs.h @@ -22,7 +22,10 @@ score.o: misc.h main.h share.h misc.o: misc.h main.h clean: - rm -f *.o advent advent.html advent.6 + rm -f *.o advent.html advent.6 + +realclean: clean + rm -f adventure.data advent430 # Requires asciidoc and xsltproc/docbook stylesheets. .asc.6: From baa508a6833690f3bf1c56a750b5798e4fd5a283 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 23 May 2017 14:48:41 -0400 Subject: [PATCH 02/23] Begin factoring out the command interpreter. --- main.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/main.c b/main.c index 6841cee..60e3dd0 100644 --- a/main.c +++ b/main.c @@ -51,6 +51,8 @@ extern int action(long); * MAIN PROGRAM */ +static void do_command(void); + int main(int argc, char *argv[]) { int ch; @@ -122,6 +124,13 @@ L1: SETUP= -1; LIMIT=330; if(NOVICE)LIMIT=1000; + for (;;) { + do_command(); + } +} + +static void do_command(void) { + /* Can't leave cave once it's closing (except by main office). */ L2: if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71; @@ -441,7 +450,7 @@ L4090: I=4090; goto Laction; L5000: I=5000; Laction: switch (action(I)) { - case 2: goto L2; + case 2: return; case 8: goto L8; case 2000: goto L2000; case 2009: goto L2009; @@ -477,7 +486,7 @@ L8000: SETPRM(1,WD1,WD1X); L8: KK=KEY[LOC]; NEWLOC=LOC; if(KK == 0)BUG(26); - if(K == NUL) goto L2; + if(K == NUL) return; if(K == BACK) goto L20; if(K == LOOK) goto L30; if(K == CAVE) goto L40; @@ -508,11 +517,11 @@ L13: if(NEWLOC <= 100) goto L14; L14: if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12; L16: NEWLOC=MOD(LL,1000); - if(NEWLOC <= 300) goto L2; + if(NEWLOC <= 300) return; if(NEWLOC <= 500) goto L30000; RSPEAK(NEWLOC-500); NEWLOC=LOC; - goto L2; + return; /* Special motions come here. Labelling convention: statement numbers NNNXX * (XX=00-99) are used for special case number NNN (NNN=301-500). */ @@ -527,10 +536,10 @@ L30000: NEWLOC=NEWLOC-300; * be used for actual motion, but can be spotted by "go back". */ L30100: NEWLOC=99+100-LOC; - if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) goto L2; + if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) return; NEWLOC=LOC; RSPEAK(117); - goto L2; + return; /* Travel 302. Plover transport. Drop the emerald (only use special travel if * toting it), so he's forced to use the plover-passage to get it out. Having @@ -554,11 +563,11 @@ L30300: if(PROP[TROLL] != 1) goto L30310; MOVE(TROLL+100,FIXD[TROLL]); JUGGLE(CHASM); NEWLOC=LOC; - goto L2; + return; L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC; if(PROP[TROLL] == 0)PROP[TROLL]=1; - if(!TOTING(BEAR)) goto L2; + if(!TOTING(BEAR)) return; RSPEAK(162); PROP[CHASM]=1; PROP[TROLL]=2; @@ -582,7 +591,7 @@ L20: K=OLDLOC; if(CNDBIT(LOC,4))K2=274; if(K2 == 0) goto L21; RSPEAK(K2); - goto L2; + return; L21: LL=MOD((IABS(TRAVEL[KK])/1000),1000); if(LL == K) goto L25; @@ -596,7 +605,7 @@ L22: if(TRAVEL[KK] < 0) goto L23; L23: KK=K2; if(KK != 0) goto L25; RSPEAK(140); - goto L2; + return; L25: K=MOD(IABS(TRAVEL[KK]),1000); KK=KEY[LOC]; @@ -609,14 +618,14 @@ L30: if(DETAIL < 3)RSPEAK(15); DETAIL=DETAIL+1; WZDARK=false; ABB[LOC]=0; - goto L2; + return; /* Cave. Different messages depending on whether above ground. */ L40: K=58; if(OUTSID(LOC) && LOC != 8)K=57; RSPEAK(K); - goto L2; + return; /* Non-applicable motion. Various messages depending on word given. */ @@ -629,7 +638,7 @@ L50: SPK=12; if(K == 62 || K == 65)SPK=42; if(K == 17)SPK=80; RSPEAK(SPK); - goto L2; + return; @@ -847,7 +856,7 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1); RSPEAK(132); CLOSED=true; - goto L2; + return; /* Another way we can force an end to things is by having the lamp give out. * When it gets close, we come here to warn him. We go to 12000 if the lamp From a416d78a58dd1336f0bcb659a20edafca0dc8387 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 23 May 2017 15:57:38 -0400 Subject: [PATCH 03/23] Input source is parametrized all the way down. This means that, potentially, do_command() could be called on any text file pointer and the right thing would happen. --- actions1.c | 14 +++++++------- actions2.c | 8 ++++---- funcs.h | 2 +- main.c | 20 ++++++++++---------- misc.c | 12 ++++++------ misc.h | 8 ++++---- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/actions1.c b/actions1.c index 1b0086b..66bad5e 100644 --- a/actions1.c +++ b/actions1.c @@ -14,7 +14,7 @@ /* Analyse a verb. Remember what it was, go back for object if second word * unless verb is "say", which snarfs arbitrary second word. */ -int action(long STARTAT) { +int action(FILE *input, long STARTAT) { switch(STARTAT) { case 4000: goto L4000; case 4090: goto L4090; @@ -269,7 +269,7 @@ L9094: DROP(JADE,LOC); /* Attack also moved into separate module. */ -L9120: return(attack()); +L9120: return(attack(input)); /* Pour. If no object, or object is bottle, assume contents of bottle. * special tests for pouring water or oil on plant or rusty door. */ @@ -349,11 +349,11 @@ L9160: if(OBJ != LAMP)SPK=76; /* Throw moved into separate module. */ -L9170: return(throw()); +L9170: return(throw(input)); /* Quit. Intransitive only. Verify intent and exit if that's what he wants. */ -L8180: if(YES(22,54,54)) score(1); +L8180: if(YES(input,22,54,54)) score(1); return(2012); /* Find. Might be carrying it, or it might be here. Else give caveat. */ @@ -446,7 +446,7 @@ L9270: if(DARK(0)) goto L5190; PSPEAK(OBJ,OBJTXT[OBJ]+PROP[OBJ]); return(2012); -L9275: CLSHNT=YES(192,193,54); +L9275: CLSHNT=YES(input,192,193,54); return(2012); /* Break. Only works for mirror in repository and, of course, the vase. */ @@ -475,7 +475,7 @@ L9290: if(OBJ != DWARF || !CLOSED) return(2011); L8300: SPK=201; RSPEAK(260); - if(!YES(200,54,54)) return(2012); + if(!YES(input,200,54,54)) return(2012); SAVED=SAVED+5; KK= -1; @@ -525,7 +525,7 @@ L8305: DATIME(I,K); L8310: KK=1; if(LOC == 1 && ABB[1] == 1) goto L8305; RSPEAK(268); - if(!YES(200,54,54)) return(2012); + if(!YES(input,200,54,54)) return(2012); goto L8305; L8312: SETPRM(1,K/10,MOD(K,10)); diff --git a/actions2.c b/actions2.c index 4385ad9..dcc649d 100644 --- a/actions2.c +++ b/actions2.c @@ -131,7 +131,7 @@ L9028: PROP[VASE]=2; * objects fall into two categories: enemies (snake, dwarf, etc.) and others * (bird, clam, machine). Ambiguous if 2 enemies, or no enemies but 2 others. */ -int attack() { +int attack(FILE *input) { I=ATDWRF(LOC); if(OBJ != 0) goto L9124; if(I > 0)OBJ=DWARF; @@ -176,7 +176,7 @@ L9126: if(OBJ == 0)SPK=44; RSPEAK(49); VERB=0; OBJ=0; - GETIN(WD1,WD1X,WD2,WD2X); + GETIN(input,WD1,WD1X,WD2,WD2X); if(WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) return(2607); PSPEAK(DRAGON,3); PROP[DRAGON]=1; @@ -214,7 +214,7 @@ L9129: /*etc*/ ; * and if dwarf is present then one might be killed. (Only way to do so!) * Axe also special for dragon, bear, and troll. Treasures special for troll. */ -int throw() { +int throw(FILE *cmdin) { if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2; if(!TOTING(OBJ)) return(2011); if(OBJ >= 50 && OBJ <= MAXTRS && AT(TROLL)) goto L9178; @@ -230,7 +230,7 @@ int throw() { if(AT(OGRE)) goto L9175; if(HERE(BEAR) && PROP[BEAR] == 0) goto L9176; OBJ=0; - return(attack()); + return(attack(cmdin)); L9172: SPK=48; if(RAN(7) < DFLAG) goto L9175; diff --git a/funcs.h b/funcs.h index e86fb2c..455de2d 100644 --- a/funcs.h +++ b/funcs.h @@ -37,7 +37,7 @@ #define OUTSID(LOC) ((LOC) <= 8 || FOREST(LOC) || (LOC) == PLAC[SAPPH] || (LOC) == 180 || (LOC) == 182) #define INDEEP(LOC) ((LOC) >= 15 && !OUTSID(LOC) && (LOC) != 179) -extern int carry(void), discard(bool), attack(void), throw(void), feed(void), fill(void); +extern int carry(void), discard(bool), attack(FILE *), throw(FILE *), feed(void), fill(void); void score(long); diff --git a/main.c b/main.c index 60e3dd0..de25b32 100644 --- a/main.c +++ b/main.c @@ -45,13 +45,13 @@ bool oldstyle = false; extern void initialise(); extern void score(long); -extern int action(long); +extern int action(FILE *, long); /* * MAIN PROGRAM */ -static void do_command(void); +static void do_command(FILE *); int main(int argc, char *argv[]) { int ch; @@ -118,18 +118,18 @@ int main(int argc, char *argv[]) { L1: SETUP= -1; I=RAN(-1); ZZWORD=RNDVOC(3,0)+MESH*2; - NOVICE=YES(65,1,0); + NOVICE=YES(stdin, 65,1,0); NEWLOC=1; LOC=1; LIMIT=330; if(NOVICE)LIMIT=1000; for (;;) { - do_command(); + do_command(stdin); } } -static void do_command(void) { +static void do_command(FILE *cmdin) { /* Can't leave cave once it's closing (except by main office). */ @@ -381,7 +381,7 @@ L2603: if(!CLOSED) goto L2605; L2605: WZDARK=DARK(0); if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0; I=RAN(1); - GETIN(WD1,WD1X,WD2,WD2X); + GETIN(cmdin, WD1,WD1X,WD2,WD2X); /* Every input, check "FOOBAR" flag. If zero, nothing's going on. If pos, * make neg. If neg, he skipped a word, so make it zero. */ @@ -449,7 +449,7 @@ L4000: I=4000; goto Laction; L4090: I=4090; goto Laction; L5000: I=5000; Laction: - switch (action(I)) { + switch (action(cmdin, I)) { case 2: return; case 8: goto L8; case 2000: goto L2000; @@ -670,7 +670,7 @@ L90: RSPEAK(23); L99: if(CLOSNG) goto L95; NUMDIE=NUMDIE+1; - if(!YES(79+NUMDIE*2,80+NUMDIE*2,54)) score(0); + if(!YES(cmdin,79+NUMDIE*2,80+NUMDIE*2,54)) score(0); if(NUMDIE == MAXDIE) score(0); PLACE[WATER]=0; PLACE[OIL]=0; @@ -713,10 +713,10 @@ L40000: switch (HINT-1) { case 0: goto L40100; case 1: goto L40200; case 2: g BUG(27); L40010: HINTLC[HINT]=0; - if(!YES(HINTS[HINT][3],0,54)) goto L2602; + if(!YES(cmdin,HINTS[HINT][3],0,54)) goto L2602; SETPRM(1,HINTS[HINT][2],HINTS[HINT][2]); RSPEAK(261); - HINTED[HINT]=YES(175,HINTS[HINT][4],54); + HINTED[HINT]=YES(cmdin,175,HINTS[HINT][4],54); if(HINTED[HINT] && LIMIT > 30)LIMIT=LIMIT+30*HINTS[HINT][2]; L40020: HINTLC[HINT]=0; L40030: goto L2602; diff --git a/misc.c b/misc.c index b1f3f83..63052ce 100644 --- a/misc.c +++ b/misc.c @@ -172,7 +172,7 @@ void fSETPRM(long FIRST, long P1, long P2) { #define WORD1X (*wORD1X) #define WORD2 (*wORD2) #define WORD2X (*wORD2X) -void fGETIN(long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) { +void fGETIN(FILE *input, long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) { long JUNK; /* Get a command from the adventurer. Snarf out the first word, pad it with @@ -183,8 +183,8 @@ long JUNK; L10: if(BLKLIN)TYPE0(); - MAPLIN(stdin); - if(feof(stdin)) score(1); + MAPLIN(input); + if(input == stdin && feof(stdin)) score(1); WORD1=GETTXT(true,true,true,0); if(BLKLIN && WORD1 < 0) goto L10; WORD1X=GETTXT(false,true,true,0); @@ -205,9 +205,9 @@ L22: JUNK=GETTXT(false,true,true,0); #undef WORD1X #undef WORD2 #undef WORD2X -#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X) +#define GETIN(SRC,WORD1,WORD1X,WORD2,WORD2X) fGETIN(SRC,&WORD1,&WORD1X,&WORD2,&WORD2X) #undef YES -long fYES(long X, long Y, long Z) { +long fYES(FILE *input, long X, long Y, long Z) { long YES, REPLY, JUNK1, JUNK2, JUNK3; @@ -215,7 +215,7 @@ long YES, REPLY, JUNK1, JUNK2, JUNK3; * if no, print Z and return false. */ L1: RSPEAK(X); - GETIN(REPLY,JUNK1,JUNK2,JUNK3); + GETIN(input, REPLY,JUNK1,JUNK2,JUNK3); if(REPLY == MAKEWD(250519) || REPLY == MAKEWD(25)) goto L10; if(REPLY == MAKEWD(1415) || REPLY == MAKEWD(14)) goto L20; RSPEAK(185); diff --git a/misc.h b/misc.h index 19612b0..561ac52 100644 --- a/misc.h +++ b/misc.h @@ -13,10 +13,10 @@ extern void fRSPEAK(long); #define RSPEAK(I) fRSPEAK(I) extern void fSETPRM(long,long,long); #define SETPRM(FIRST,P1,P2) fSETPRM(FIRST,P1,P2) -extern void fGETIN(long*,long*,long*,long*); -#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X) -extern long fYES(long,long,long); -#define YES(X,Y,Z) fYES(X,Y,Z) +extern void fGETIN(FILE *,long*,long*,long*,long*); +#define GETIN(input,WORD1,WORD1X,WORD2,WORD2X) fGETIN(input,&WORD1,&WORD1X,&WORD2,&WORD2X) +extern long fYES(FILE *,long,long,long); +#define YES(input,X,Y,Z) fYES(input,X,Y,Z) extern long fGETNUM(FILE *); #define GETNUM(K) fGETNUM(K) extern long fGETTXT(long,long,long,long); From 63efff14f5e219309bdd5e1b219373bf49605d8d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 23 May 2017 20:38:46 -0400 Subject: [PATCH 04/23] Echo commands to stdout when replaying... ...makes check loads full transcripts abd more readable. --- misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc.c b/misc.c index 63052ce..1ca50d8 100644 --- a/misc.c +++ b/misc.c @@ -894,6 +894,8 @@ long I, VAL; } else { if (logfp) IGNORE(fputs(INLINE+1, logfp)); + else if (!isatty(0)) + IGNORE(fputs(INLINE+1, stdout)); LNLENG=0; for (I=1; I<=sizeof(INLINE) && INLINE[I]!=0; I++) { VAL=INLINE[I]+1; From 97b00dfb147534b2ac86bacbb4445bdb2a0ecdbb Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 23 May 2017 22:29:24 -0400 Subject: [PATCH 05/23] Make output from replays easier to interpret by adding prompts. --- misc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 1ca50d8..680f9ff 100644 --- a/misc.c +++ b/misc.c @@ -894,8 +894,10 @@ long I, VAL; } else { if (logfp) IGNORE(fputs(INLINE+1, logfp)); - else if (!isatty(0)) + else if (!isatty(0)) { + IGNORE(fputs("> ", stdout)); IGNORE(fputs(INLINE+1, stdout)); + } LNLENG=0; for (I=1; I<=sizeof(INLINE) && INLINE[I]!=0; I++) { VAL=INLINE[I]+1; From 5598b7a178a486bf8ec33341357d4c9248566539 Mon Sep 17 00:00:00 2001 From: "Jason S. Ninneman" Date: Tue, 23 May 2017 23:37:56 -0700 Subject: [PATCH 06/23] Add seedable PRNG using an adaptation the original LCG algorithm. --- TODO | 3 +-- actions2.c | 2 +- funcs.h | 2 +- main.c | 18 +++++++++++++----- main.h | 6 ++++++ misc.c | 46 +++++++++++++++++++++++----------------------- misc.h | 5 +++-- 7 files changed, 48 insertions(+), 34 deletions(-) diff --git a/TODO b/TODO index 3fe80a7..78e4e07 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ = Open Adventure TODO = -* Use a real pseudorandom-number generator with a seed rather than just - time-sampling. +* Update the command parser to accept a PRNG seed value. * Add command logging and command log replay. Note that the replay log needs to begin with the random-number seed. diff --git a/actions2.c b/actions2.c index dcc649d..6b28895 100644 --- a/actions2.c +++ b/actions2.c @@ -233,7 +233,7 @@ int throw(FILE *cmdin) { return(attack(cmdin)); L9172: SPK=48; - if(RAN(7) < DFLAG) goto L9175; + if(randrange(7) < DFLAG) goto L9175; DSEEN[I]=false; DLOC[I]=0; SPK=47; diff --git a/funcs.h b/funcs.h index 455de2d..deb4010 100644 --- a/funcs.h +++ b/funcs.h @@ -23,7 +23,7 @@ #define CNDBIT(L,N) (TSTBIT(COND[L],N)) #define FORCED(LOC) (COND[LOC] == 2) #define DARK(DUMMY) ((!CNDBIT(LOC,0)) && (PROP[LAMP] == 0 || !HERE(LAMP))) -#define PCT(N) (RAN(100) < (N)) +#define PCT(N) (randrange(100) < (N)) #define GSTONE(OBJ) ((OBJ) == EMRALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH) #define FOREST(LOC) ((LOC) >= 145 && (LOC) <= 166) #define VOCWRD(LETTRS,SECT) (VOCAB(MAKEWD(LETTRS),SECT)) diff --git a/main.c b/main.c index de25b32..a3051ab 100644 --- a/main.c +++ b/main.c @@ -42,6 +42,7 @@ long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BO WZDARK = false, ZZWORD; FILE *logfp; bool oldstyle = false; +lcg_state lcgstate; extern void initialise(); extern void score(long); @@ -93,6 +94,13 @@ int main(int argc, char *argv[]) { #include "funcs.h" +/* Initialize our LCG PRNG with parameters tested against Knuth vol. 2. by the original authors */ + + lcgstate.a = 1093; + lcgstate.c = 221587; + lcgstate.m = 1048576; + set_seed_from_time(); + /* Read the database if we have not yet done so */ LINES = (long *)calloc(LINSIZ+1,sizeof(long)); @@ -116,7 +124,7 @@ int main(int argc, char *argv[]) { /* Start-up, dwarf stuff */ L1: SETUP= -1; - I=RAN(-1); + I=0; ZZWORD=RNDVOC(3,0)+MESH*2; NOVICE=YES(stdin, 65,1,0); NEWLOC=1; @@ -175,7 +183,7 @@ L6000: if(DFLAG != 1) goto L6010; if(!INDEEP(LOC) || (PCT(95) && (!CNDBIT(LOC,4) || PCT(85)))) goto L2000; DFLAG=2; for (I=1; I<=2; I++) { - J=1+RAN(5); + J=1+randrange(5); if(PCT(50))DLOC[J]=0; } /* end loop */ for (I=1; I<=5; I++) { @@ -213,7 +221,7 @@ L6014: KK=KK+1; {long x = KK-1; if(TRAVEL[x] >= 0) goto L6012;} L6016: TK[J]=ODLOC[I]; if(J >= 2)J=J-1; - J=1+RAN(J); + J=1+randrange(J); ODLOC[I]=DLOC[I]; DLOC[I]=TK[J]; DSEEN[I]=(DSEEN[I] && INDEEP(LOC)) || (DLOC[I] == LOC || ODLOC[I] == LOC); @@ -266,7 +274,7 @@ L6027: DTOTAL=DTOTAL+1; if(ODLOC[I] != DLOC[I]) goto L6030; ATTACK=ATTACK+1; if(KNFLOC >= 0)KNFLOC=LOC; - if(RAN(1000) < 95*(DFLAG-2))STICK=STICK+1; + if(randrange(1000) < 95*(DFLAG-2))STICK=STICK+1; L6030: /*etc*/ ; } /* end loop */ @@ -380,7 +388,7 @@ L2603: if(!CLOSED) goto L2605; } /* end loop */ L2605: WZDARK=DARK(0); if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0; - I=RAN(1); + I=0; GETIN(cmdin, WD1,WD1X,WD2,WD2X); /* Every input, check "FOOBAR" flag. If zero, nothing's going on. If pos, diff --git a/main.h b/main.h index fa87d62..a71b9e3 100644 --- a/main.h +++ b/main.h @@ -2,9 +2,15 @@ #define LINESIZE 100 +typedef struct lcg_state +{ + unsigned long a, c, m, x; +} lcg_state; + extern long ABB[], ATAB[], ATLOC[], BLKLIN, DFLAG, DLOC[], FIXED[], HOLDNG, KTAB[], *LINES, LINK[], LNLENG, LNPOSN, PARMS[], PLACE[], PTEXT[], RTEXT[], TABSIZ; extern signed char INLINE[LINESIZE+1], MAP1[], MAP2[]; extern FILE *logfp; extern bool oldstyle; +extern lcg_state lcgstate; diff --git a/misc.c b/misc.c index 680f9ff..7d9f4ec 100644 --- a/misc.c +++ b/misc.c @@ -722,7 +722,7 @@ L2: ATDWRF=I; -/* Utility routines (SETBIT, TSTBIT, RAN, RNDVOC, BUG) */ +/* Utility routines (SETBIT, TSTBIT, set_seed_from_time, get_next_lcg_value, randrange, RNDVOC, BUG) */ #undef SETBIT long fSETBIT(long BIT) { @@ -756,32 +756,32 @@ long TSTBIT; #define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT) -#undef RAN -long fRAN(long RANGE) { -static long D, R = 0, RAN, T; +#undef RNDVOC -/* Since the ran function in LIB40 seems to be a real lose, we'll use one of - * our own. It's been run through many of the tests in Knuth vol. 2 and - * seems to be quite reliable. RAN returns a value uniformly selected - * between 0 and range-1. */ - - - D=1; - if(R != 0 && RANGE >= 0) goto L1; - DATIME(D,T); - R=MOD(T+5,1048576L); - D=1000+MOD(D,1000); -L1: for (T=1; T<=D; T++) { - R=MOD(R*1093L+221587L,1048576L); - } /* end loop */ - RAN=(RANGE*R)/1048576; - return(RAN); +void set_seed_from_time(void) +{ + /* Use the current system time to get seed the ISO rand() function, from which we get a seed for the LCG. */ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + srand(ts.tv_nsec); + lcgstate.x = (unsigned long) rand() % lcgstate.m; } +unsigned long get_next_lcg_value(void) +{ + /* Return the LCG's current value, and then iterate it. */ + unsigned long old_x = lcgstate.x; + lcgstate.x = (lcgstate.a * lcgstate.x + lcgstate.c) % lcgstate.m; + return(old_x); +} +long randrange(long range) +{ + /* Return a random integer from [0, range). */ + long result = range * get_next_lcg_value() / lcgstate.m; + return(result); +} -#define RAN(RANGE) fRAN(RANGE) -#undef RNDVOC long fRNDVOC(long CHAR, long FORCE) { long DIV, I, J, RNDVOC; @@ -794,7 +794,7 @@ long DIV, I, J, RNDVOC; RNDVOC=FORCE; if(RNDVOC != 0) goto L3; for (I=1; I<=5; I++) { - J=11+RAN(26); + J=11+randrange(26); if(I == 2)J=CHAR; RNDVOC=RNDVOC*64+J; } /* end loop */ diff --git a/misc.h b/misc.h index 561ac52..869c672 100644 --- a/misc.h +++ b/misc.h @@ -55,8 +55,6 @@ extern long fSETBIT(long); #define SETBIT(BIT) fSETBIT(BIT) extern long fTSTBIT(long,long); #define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT) -extern long fRAN(long); -#define RAN(RANGE) fRAN(RANGE) extern long fRNDVOC(long,long); #define RNDVOC(CHAR,FORCE) fRNDVOC(CHAR,FORCE) extern void fBUG(long); @@ -74,3 +72,6 @@ extern long fIABS(long); #define IABS(N) fIABS(N) extern long fMOD(long,long); #define MOD(N,M) fMOD(N,M) +extern void set_seed_from_time(void); +extern unsigned long get_next_lcg_value(void); +extern long randrange(long); From 060601da2fcb174f87489489431529aa3e9f694a Mon Sep 17 00:00:00 2001 From: "Jason S. Ninneman" Date: Tue, 23 May 2017 23:46:20 -0700 Subject: [PATCH 07/23] Remove a bad use of tv_nsec. --- misc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/misc.c b/misc.c index 7d9f4ec..18bdd7a 100644 --- a/misc.c +++ b/misc.c @@ -761,9 +761,7 @@ long TSTBIT; void set_seed_from_time(void) { /* Use the current system time to get seed the ISO rand() function, from which we get a seed for the LCG. */ - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - srand(ts.tv_nsec); + srand(time(NULL)); lcgstate.x = (unsigned long) rand() % lcgstate.m; } From 54afefba9497d22db706df30eee2cfc68f59892f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 24 May 2017 23:05:19 -0400 Subject: [PATCH 08/23] Re-enable skipping of #-led comments. --- misc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/misc.c b/misc.c index 18bdd7a..04107c7 100644 --- a/misc.c +++ b/misc.c @@ -883,9 +883,12 @@ long I, VAL; if(MAP2[1] == 0)MPINIT(); - if (!oldstyle && isatty(0)) - fputs("> ", stdout); - IGNORE(fgets(INLINE+1,sizeof(INLINE)-1,OPENED)); + if (!oldstyle && OPENED == stdin) + fputs("> ", stdout); + do { + IGNORE(fgets(INLINE+1,sizeof(INLINE)-1,OPENED)); + } while + (!feof(OPENED) && INLINE[1] == '#'); if (feof(OPENED)) { if (logfp) fclose(logfp); From 2fdd509f328b8530f6e896cc6f1edf89c53bfb75 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 24 May 2017 23:36:25 -0400 Subject: [PATCH 09/23] Once again, take srand()/random() out of the initialization chain. They have exactly the wrong kind of randomness for this job - not returning consistent sequences across different platforms or C library versions, and because pseodorandom not really better than sampling the clock. --- main.c | 2 +- misc.c | 9 ++++----- misc.h | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index a3051ab..616a57f 100644 --- a/main.c +++ b/main.c @@ -99,7 +99,7 @@ int main(int argc, char *argv[]) { lcgstate.a = 1093; lcgstate.c = 221587; lcgstate.m = 1048576; - set_seed_from_time(); + set_seed((long)time(NULL)); /* Read the database if we have not yet done so */ diff --git a/misc.c b/misc.c index 04107c7..3243f1e 100644 --- a/misc.c +++ b/misc.c @@ -722,7 +722,8 @@ L2: ATDWRF=I; -/* Utility routines (SETBIT, TSTBIT, set_seed_from_time, get_next_lcg_value, randrange, RNDVOC, BUG) */ +/* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value, + * randrange, RNDVOC, BUG) */ #undef SETBIT long fSETBIT(long BIT) { @@ -758,11 +759,9 @@ long TSTBIT; #define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT) #undef RNDVOC -void set_seed_from_time(void) +void set_seed(long seedval) { - /* Use the current system time to get seed the ISO rand() function, from which we get a seed for the LCG. */ - srand(time(NULL)); - lcgstate.x = (unsigned long) rand() % lcgstate.m; + lcgstate.x = (unsigned long) seedval % lcgstate.m; } unsigned long get_next_lcg_value(void) diff --git a/misc.h b/misc.h index 869c672..67f1e9b 100644 --- a/misc.h +++ b/misc.h @@ -72,6 +72,6 @@ extern long fIABS(long); #define IABS(N) fIABS(N) extern long fMOD(long,long); #define MOD(N,M) fMOD(N,M) -extern void set_seed_from_time(void); +extern void set_seed(long); extern unsigned long get_next_lcg_value(void); extern long randrange(long); From 74dc437a7e7644e18d3cc6192f92d2f92a394106 Mon Sep 17 00:00:00 2001 From: "Jason S. Ninneman" Date: Wed, 24 May 2017 22:31:26 -0700 Subject: [PATCH 10/23] Stop command-logging from non-stdin sources. --- misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 3243f1e..3bca473 100644 --- a/misc.c +++ b/misc.c @@ -892,7 +892,7 @@ long I, VAL; if (logfp) fclose(logfp); } else { - if (logfp) + if (logfp && OPENED == stdin) IGNORE(fputs(INLINE+1, logfp)); else if (!isatty(0)) { IGNORE(fputs("> ", stdout)); From f286c3a327f90c867edd5806098a90d1b4f10057 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 25 May 2017 18:21:38 -0400 Subject: [PATCH 11/23] Implement fallback handler that looks at the raw command buffer. --- main.c | 12 ++++++++++-- main.h | 2 +- misc.c | 12 ++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/main.c b/main.c index 616a57f..1288540 100644 --- a/main.c +++ b/main.c @@ -16,7 +16,7 @@ long ABB[186], ATAB[331], ATLOC[186], BLKLIN = true, DFLAG, KTAB[331], *LINES, LINK[201], LNLENG, LNPOSN, PARMS[26], PLACE[101], PTEXT[101], RTEXT[278], SETUP = 0, TABSIZ = 330; -signed char INLINE[LINESIZE+1], MAP1[129], MAP2[129]; +signed char rawbuf[LINESIZE], INLINE[LINESIZE+1], MAP1[129], MAP2[129]; long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BONUS, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2, @@ -137,8 +137,14 @@ L1: SETUP= -1; } } -static void do_command(FILE *cmdin) { +static bool fallback_handler(signed char *buf) +/* fallback handler for commands not handled by FORTRANish parser */ +{ + printf("Fallback handler sees: %s\n", buf); + return false; +} +static void do_command(FILE *cmdin) { /* Can't leave cave once it's closing (except by main office). */ L2: if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71; @@ -448,6 +454,8 @@ L2800: WD1=WD2; /* Gee, I don't understand. */ L3000: SETPRM(1,WD1,WD1X); + if (fallback_handler(rawbuf)) + return; RSPEAK(254); goto L2600; diff --git a/main.h b/main.h index a71b9e3..184acee 100644 --- a/main.h +++ b/main.h @@ -10,7 +10,7 @@ typedef struct lcg_state extern long ABB[], ATAB[], ATLOC[], BLKLIN, DFLAG, DLOC[], FIXED[], HOLDNG, KTAB[], *LINES, LINK[], LNLENG, LNPOSN, PARMS[], PLACE[], PTEXT[], RTEXT[], TABSIZ; -extern signed char INLINE[LINESIZE+1], MAP1[], MAP2[]; +extern signed char rawbuf[LINESIZE], INLINE[LINESIZE+1], MAP1[], MAP2[]; extern FILE *logfp; extern bool oldstyle; extern lcg_state lcgstate; diff --git a/misc.c b/misc.c index 3bca473..b80d9b8 100644 --- a/misc.c +++ b/misc.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "main.h" #include "misc.h" #include "funcs.h" @@ -885,7 +886,7 @@ long I, VAL; if (!oldstyle && OPENED == stdin) fputs("> ", stdout); do { - IGNORE(fgets(INLINE+1,sizeof(INLINE)-1,OPENED)); + IGNORE(fgets(rawbuf,sizeof(INLINE)-1,OPENED)); } while (!feof(OPENED) && INLINE[1] == '#'); if (feof(OPENED)) { @@ -893,11 +894,10 @@ long I, VAL; fclose(logfp); } else { if (logfp && OPENED == stdin) - IGNORE(fputs(INLINE+1, logfp)); - else if (!isatty(0)) { - IGNORE(fputs("> ", stdout)); - IGNORE(fputs(INLINE+1, stdout)); - } + IGNORE(fputs(rawbuf, logfp)); + else if (!isatty(0)) + IGNORE(fputs(rawbuf, stdout)); + strcpy(INLINE+1, rawbuf); LNLENG=0; for (I=1; I<=sizeof(INLINE) && INLINE[I]!=0; I++) { VAL=INLINE[I]+1; From 85cd6b0bd573834d5004b70e3222a927f7e7bac8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 25 May 2017 18:52:39 -0400 Subject: [PATCH 12/23] Repeatable seeding is working. --- main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 1288540..5a7c523 100644 --- a/main.c +++ b/main.c @@ -99,7 +99,8 @@ int main(int argc, char *argv[]) { lcgstate.a = 1093; lcgstate.c = 221587; lcgstate.m = 1048576; - set_seed((long)time(NULL)); + long seedval = (long)time(NULL); + set_seed(seedval); /* Read the database if we have not yet done so */ @@ -132,6 +133,9 @@ L1: SETUP= -1; LIMIT=330; if(NOVICE)LIMIT=1000; + if (logfp) + fprintf(logfp, "seed %ld\n", seedval); + for (;;) { do_command(stdin); } @@ -140,7 +144,12 @@ L1: SETUP= -1; static bool fallback_handler(signed char *buf) /* fallback handler for commands not handled by FORTRANish parser */ { - printf("Fallback handler sees: %s\n", buf); + long sv; + if (sscanf(buf, "seed %ld", &sv) == 1) { + set_seed(sv); + printf("Seed set to %ld\n", sv); + return true; + } return false; } From d39325f96382d3b6deef503ff6d14f74289bd411 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 26 May 2017 05:14:18 -0400 Subject: [PATCH 13/23] Fix bug that led to comments not being ignored. --- misc.c | 4 +- tests/death-jump.chk | 140 ++++++++++++++++ tests/dwarf.chk | 389 +++++++++++++++++++++++++++++++++++++++++++ tests/quit.chk | 22 +++ 4 files changed, 553 insertions(+), 2 deletions(-) create mode 100644 tests/death-jump.chk create mode 100644 tests/dwarf.chk create mode 100644 tests/quit.chk diff --git a/misc.c b/misc.c index b80d9b8..9e18c74 100644 --- a/misc.c +++ b/misc.c @@ -886,9 +886,9 @@ long I, VAL; if (!oldstyle && OPENED == stdin) fputs("> ", stdout); do { - IGNORE(fgets(rawbuf,sizeof(INLINE)-1,OPENED)); + IGNORE(fgets(rawbuf,sizeof(rawbuf)-1,OPENED)); } while - (!feof(OPENED) && INLINE[1] == '#'); + (!feof(OPENED) && rawbuf[0] == '#'); if (feof(OPENED)) { if (logfp) fclose(logfp); diff --git a/tests/death-jump.chk b/tests/death-jump.chk new file mode 100644 index 0000000..55e648c --- /dev/null +++ b/tests/death-jump.chk @@ -0,0 +1,140 @@ + +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. + +> seed 1495774850 +Seed set to 1495774850 + +You're in front of building. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> take keys + +OK + +> take lamp + +OK + +> out + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> s + +At your feet all the water of the stream splashes into a 2-inch slit +in the rock. Downstream the streambed is bare rock. + +> s + +You are in a 20-foot depression floored with bare dirt. Set into the +dirt is a strong steel grate mounted in concrete. A dry streambed +leads into the depression. + +The grate is locked. + +> open grate + +The grate is now unlocked. + +> d + +You are in a small chamber beneath a 3x3 steel grate to the surface. +A low crawl over cobbles leads inward to the west. + +The grate is open. + +> w + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> w + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> light lamp + +Your lamp is now on. + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> w + +You are in an awkward sloping east/west canyon. + +> w + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> w + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> down + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> jump + +You didn't make it. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> n + +OK + +You scored 51 out of a possible 430, using 19 turns. + +Your score qualifies you as a novice class adventurer. + +To achieve the next higher rating, you need 70 more points. diff --git a/tests/dwarf.chk b/tests/dwarf.chk new file mode 100644 index 0000000..fcf3a1e --- /dev/null +++ b/tests/dwarf.chk @@ -0,0 +1,389 @@ + +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. + +> seed 1495763690 +Seed set to 1495763690 + +You're in front of building. + +> seed 1495752222 +Seed set to 1495752222 + +You're in front of building. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> take keys + +OK + +> take lamp + +OK + +> out + +You're in front of building. + +> down + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> s + +At your feet all the water of the stream splashes into a 2-inch slit +in the rock. Downstream the streambed is bare rock. + +> s + +You are in a 20-foot depression floored with bare dirt. Set into the +dirt is a strong steel grate mounted in concrete. A dry streambed +leads into the depression. + +The grate is locked. + +> open grate + +The grate is now unlocked. + +> down + +You are in a small chamber beneath a 3x3 steel grate to the surface. +A low crawl over cobbles leads inward to the west. + +The grate is open. + +> west + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> west + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> light lamp + +Your lamp is now on. + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> xyzzy + +>>Foof!<< + +You're inside building. + +There is food here. + +There is a bottle of water here. + +> xyzzy + +>>Foof!<< + +You're in debris room. + +> west + +You are in an awkward sloping east/west canyon. + +> drop rod + +OK + +> west + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> take bird + +OK + +> east + +You are in an awkward sloping east/west canyon. + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> west + +You're in bird chamber. + +> west + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> down + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> south + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take gold + +OK + +> n + +You're in Hall of Mists. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> drop bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> west + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +A cheerful little bird is sitting here singing. + +> s + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You are in the south side chamber. + +There is a little axe here. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in Hall of Mt King. + +A cheerful little bird is sitting here singing. + +> n + +There is a threatening little dwarf in the room with you! + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> take silver + +You can't carry anything more. You'll have to drop something first. + +> drop cage + +OK + +> take silver + +OK + +> n + +There is a threatening little dwarf in the room with you! + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +> plugh + +>>Foof!<< + +You're inside building. + +There is food here. + +There is a bottle of water here. + +> inven + +You are currently holding the following: +Set of keys +Brass lantern +Black rod +Large gold nugget +Bars of silver +Precious jewelry +Rare coins + +> drop jewelry + +OK + +> drop gold + +OK + +> drop silver + +OK + +> inven + +You are currently holding the following: +Set of keys +Brass lantern +Black rod +Rare coins + +> drop keys + +OK + +> plugh + +>>Foof!<< + +There are 2 threatening little dwarves in the room with you. + +One sharp nasty knife is thrown at you! + +It misses! + +You're at "Y2". + +> take knife + +The dwarves' knives vanish as they strike the walls of the cave. + +> throw axe + +I see no axe here. + +> s + +There are 2 threatening little dwarves in the room with you. + +You're in n/s passage above e/w passage. + +There is a small wicker cage discarded nearby. + +> s + +There are 2 threatening little dwarves in the room with you. + +You're in Hall of Mt King. + +A cheerful little bird is sitting here singing. + +> up + +There are 2 threatening little dwarves in the room with you. + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +There are 2 threatening little dwarves in the room with you. + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> w + +There are 2 threatening little dwarves in the room with you. + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge now spans the fissure. + +> take diamonds + +OK + +> +You scored 97 out of a possible 430, using 60 turns. + +Your score qualifies you as a novice class adventurer. + +To achieve the next higher rating, you need 24 more points. diff --git a/tests/quit.chk b/tests/quit.chk new file mode 100644 index 0000000..87a8d98 --- /dev/null +++ b/tests/quit.chk @@ -0,0 +1,22 @@ + +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. + +> quit + +Do you really want to quit now? + +> yes + +OK + +You scored 32 out of a possible 430, using 1 turn. + +You are obviously a rank amateur. Better luck next time. + +To achieve the next higher rating, you need 14 more points. From c41dd3526880155c3498b42cbd58eb8ad71ba6aa Mon Sep 17 00:00:00 2001 From: "Jason S. Ninneman" Date: Fri, 26 May 2017 16:34:16 -0700 Subject: [PATCH 14/23] Ensure the ZZZZ magic word is reproducible. This happens by making the SEED command also regenerate the magic word. --- main.c | 2 ++ tests/dwarf.chk | 5 +++++ tests/dwarf.log | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 tests/dwarf.log diff --git a/main.c b/main.c index 5a7c523..271e8a7 100644 --- a/main.c +++ b/main.c @@ -148,6 +148,8 @@ static bool fallback_handler(signed char *buf) if (sscanf(buf, "seed %ld", &sv) == 1) { set_seed(sv); printf("Seed set to %ld\n", sv); + // here we reconfigure any global game state that uses random numbers + ZZWORD=RNDVOC(3,0)+MESH*2; return true; } return false; diff --git a/tests/dwarf.chk b/tests/dwarf.chk index fcf3a1e..2f7f6d7 100644 --- a/tests/dwarf.chk +++ b/tests/dwarf.chk @@ -7,6 +7,7 @@ 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. +<<<<<<< HEAD > seed 1495763690 Seed set to 1495763690 @@ -14,6 +15,10 @@ You're in front of building. > seed 1495752222 Seed set to 1495752222 +======= +> seed 1494912171 +Seed set to 1494912171 +>>>>>>> f9eca41 (Ensure the ZZZZ magic word is reproducible.) You're in front of building. diff --git a/tests/dwarf.log b/tests/dwarf.log new file mode 100644 index 0000000..b50a35f --- /dev/null +++ b/tests/dwarf.log @@ -0,0 +1,59 @@ +## Death by dwarf. +n +seed 1494912171 +in +take keys +take lamp +out +down +s +s +open grate +down +west +take cage +west +light lamp +take rod +xyzzy +xyzzy +west +drop rod +west +take bird +east +take rod +west +west +down +south +take gold +n +n +drop bird +west +take coins +e +s +drop cage +take jewelry +take axe +n +n +n +plugh +inven +drop jewelry +drop gold +inven +drop keys +plugh +s +s +up +w +wave rod +w +take diamonds +e +n From 220cf2c58ba33f95836ff95df10e570c87297368 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Jun 2017 16:06:21 -0400 Subject: [PATCH 15/23] Make it possible to pass options to advent from within regression-test loads. --- tests/Makefile | 46 ++++++++++++++++++++++++++++++++++++++++++++++ tests/oldstyle.log | 5 +++++ 2 files changed, 51 insertions(+) create mode 100644 tests/Makefile create mode 100644 tests/oldstyle.log diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..16a1d54 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,46 @@ +# Test-suite makefile for reposurgeon + +# Use absolute path so tests that change working directory still use +# scripts from parent directory. Note that using $PWD seems to fail +# here under Gitlab's CI environment. +PATH := $(realpath ..):$(realpath .):${PATH} + +# Defeat annoying behavior under Mac OS X - builtin echo doesn't do -n +ECHO := /bin/echo + +all: regress + @echo "=== No diff output is good news." + +.SUFFIXES: .chk + +clean: + rm -fr *~ adventure.text + +# Show summary lines for all tests. +testlist: + @grep '^##' *.log +listcheck: + @for f in *.log; do \ + if ( head -3 $$f | grep -q '^ *##' ); then :; else echo "$$f needs a description"; fi; \ + done + +# General regression testing of commands and output; look at the *.log and +# corresponding *.chk files to see which tests this runs. +TESTLOADS := $(shell ls -1 *.log | sed '/.log/s///') +buildregress: + @for file in $(TESTLOADS); do \ + echo "Remaking $${file}.chk"; \ + OPTS=`sed -n /#options:/s///p <$${file}.log`; \ + advent $$OPTS <$${file}.log >$${file}.chk 2>&1 || exit 1; \ + done +regress: + @for file in $(TESTLOADS); do \ + $(ECHO) -n " $${file} "; grep '##' $${file}.log || echo ' ## (no description)'; \ + OPTS=`sed -n /#options:/s///p <$${file}.log`; \ + if advent $$OPTS < $${file}.log >/tmp/regress$$$$ 2>&1; \ + then diff --text -u $${file}.chk /tmp/regress$$$$ || exit 1; \ + else echo "*** Nonzero return status on $${file}!"; exit 1; fi \ + done + @rm -f /tmp/regress$$$$ + +# end diff --git a/tests/oldstyle.log b/tests/oldstyle.log new file mode 100644 index 0000000..ae6f7fe --- /dev/null +++ b/tests/oldstyle.log @@ -0,0 +1,5 @@ +## Simple quit +#options: -o +n +quit +yes From b80d1779e689caacf6a4d39581e04dadb7097870 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Jun 2017 16:08:19 -0400 Subject: [PATCH 16/23] Fix dropped stitch in last commit. --- tests/oldstyle.chk | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/oldstyle.chk diff --git a/tests/oldstyle.chk b/tests/oldstyle.chk new file mode 100644 index 0000000..4ea24ee --- /dev/null +++ b/tests/oldstyle.chk @@ -0,0 +1,23 @@ +Initialising... + +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. + +quit + +Do you really want to quit now? + +yes + +OK + +You scored 32 out of a possible 430, using 1 turn. + +You are obviously a rank amateur. Better luck next time. + +To achieve the next higher rating, you need 14 more points. From 184e981be31204b30ff2b9bb747a08ccc742c155 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 30 May 2017 20:08:55 -0400 Subject: [PATCH 17/23] Fix things so seed doesn't cost clock time. --- main.c | 2 + tests/death-jump.chk | 2 +- tests/dwarf.chk | 22 + tests/pirate.chk | 1909 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1934 insertions(+), 1 deletion(-) create mode 100644 tests/pirate.chk diff --git a/main.c b/main.c index 271e8a7..398081d 100644 --- a/main.c +++ b/main.c @@ -148,6 +148,8 @@ static bool fallback_handler(signed char *buf) if (sscanf(buf, "seed %ld", &sv) == 1) { set_seed(sv); printf("Seed set to %ld\n", sv); + // autogenerated, so don't charge user time for it. + --TURNS; // here we reconfigure any global game state that uses random numbers ZZWORD=RNDVOC(3,0)+MESH*2; return true; diff --git a/tests/death-jump.chk b/tests/death-jump.chk index 55e648c..9f7e6ad 100644 --- a/tests/death-jump.chk +++ b/tests/death-jump.chk @@ -133,7 +133,7 @@ to try to reincarnate you? OK -You scored 51 out of a possible 430, using 19 turns. +You scored 51 out of a possible 430, using 18 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/dwarf.chk b/tests/dwarf.chk index 2f7f6d7..570ff83 100644 --- a/tests/dwarf.chk +++ b/tests/dwarf.chk @@ -386,8 +386,30 @@ A crystal bridge now spans the fissure. OK +<<<<<<< HEAD > You scored 97 out of a possible 430, using 60 turns. +======= +> e + +A little dwarf with a big knife blocks your way. + +There are 2 threatening little dwarves in the room with you. + +2 of them throw knives at you! + +One of them gets you! + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> n + +OK + +You scored 81 out of a possible 430, using 55 turns. +>>>>>>> 6a6670e (Fix things so seed doesn't cost clock time.) Your score qualifies you as a novice class adventurer. diff --git a/tests/pirate.chk b/tests/pirate.chk new file mode 100644 index 0000000..dbfd13d --- /dev/null +++ b/tests/pirate.chk @@ -0,0 +1,1909 @@ + +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. + +> seed 1495951709 +Seed set to 1495951709 + +You're in front of building. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> take lamp + +OK + +> on + +Your lamp is now on. + +> xyzzy + +>>Foof!<< + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> w + +You're in debris room. + +> w + +You are in an awkward sloping east/west canyon. + +> w + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> w + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> free bird + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take jade + +OK + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +The bird flies agitatedly about the cage. + +A crystal bridge now spans the fissure. + +> drop rod + +OK + +> e + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> free bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> take bird + +OK + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +> sw + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You're in Hall of Mt King. + +> n + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> take silver + +OK + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> drop silver + +OK + +> drop jewelry + +OK + +> drop jade + +OK + +> drop rug + +OK + +> out + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> free bird + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "Q'IBJ". You +thank the bird for this information, and it flies off into the forest. + +> s + +You are wandering aimlessly through the forest. + +> s + +You're in valley. + +> n + +You're in front of building. + +> in + +You're inside building. + +There is a persian rug spread out on the floor! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are bars of silver here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> take water + +OK + +> plugh + +>>Foof!<< + +You're at "Y2". + +> plover + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> ne + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You're in the dark-room. A corridor leading south is the only exit. + +There is a little axe here. + +A massive stone tablet imbedded in the wall reads: +"Congratulations on bringing light into the dark-room!" + +There is a platinum pyramid here, 8 inches on a side! + +> take axe + +OK + +> take pyramid + +OK + +> s + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> plover + +>>Foof!<< + +There is a threatening little dwarf in the room with you! + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +There is a threatening little dwarf in the room with you! + +You're in n/s passage above e/w passage. + +> d + +There is a threatening little dwarf in the room with you! + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> u + +A little dwarf with a big knife blocks your way. + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in dirty passage. + +> u + +There are 2 threatening little dwarves in the room with you. + +You're in n/s passage above e/w passage. + +> throw axe + +You attack a little dwarf, but he dodges out of the way. + +There are 2 threatening little dwarves in the room with you. + +2 of them throw knives at you! + +None of them hits you! + +You're in n/s passage above e/w passage. + +There is a little axe here. + +> take axe + +OK + +> throw axe + +You attack a little dwarf, but he dodges out of the way. + +There are 2 threatening little dwarves in the room with you. + +2 of them throw knives at you! + +None of them hits you! + +You're in n/s passage above e/w passage. + +There is a little axe here. + +> take axe + +OK + +> throw axe + +You attack a little dwarf, but he dodges out of the way. + +There are 2 threatening little dwarves in the room with you. + +2 of them throw knives at you! + +None of them hits you! + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There is a little axe here. + +> take axe + +OK + +> throw axe + +You killed a little dwarf. The body vanishes in a cloud of greasy +black smoke. + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in n/s passage above e/w passage. + +There is a little axe here. + +> take axe + +OK + +> s + +There is a threatening little dwarf in the room with you! + +You're in Hall of Mt King. + +> e + +There is a threatening little dwarf in the room with you! + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +There is a threatening little dwarf in the room with you! + +You're on east bank of fissure. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge now spans the fissure. + +> drop cage + +OK + +> w + +There is a threatening little dwarf in the room with you! + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge now spans the fissure. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> sw + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisty passages, all different. + +> se + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> kill machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> n + +You are in a little maze of twisty passages, all different. + +> nw + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> e + +You're at east end of long hall. + +> e + +You're at west end of Hall of Mists. + +> e + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge now spans the fissure. + +> take diamonds + +OK + +> e + +You're on east bank of fissure. + +There is a small wicker cage discarded nearby. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge now spans the fissure. + +> e + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take gold + +You can't carry anything more. You'll have to drop something first. + +> n + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> y2 + +You are in a jumble of rock, with cracks everywhere. + +> d + +You're at "Y2". + +> plugh + +>>Foof!<< + +You're inside building. + +There is a persian rug spread out on the floor! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are bars of silver here! + +There are some keys on the ground here. + +There is food here. + +> drop diamonds + +OK + +> drop pyramid + +OK + +> drop ruby + +OK + +> plugh + +>>Foof!<< + +You're at "Y2". + +A hollow voice says "PLUGH". + +> plugh + +>>Foof!<< + +You're inside building. + +There is an enormous ruby here! + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There is a persian rug spread out on the floor! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are bars of silver here! + +There are some keys on the ground here. + +There is food here. + +> drop coins + +I see no coins here. + +> plugh + +>>Foof!<< + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +> s + +You're in n/s passage above e/w passage. + +> d + +You're in dirty passage. + +> bedquilt + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> slab + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> w + +You're in Slab Room. + +> u + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> Q'IBJ + +The waters have parted to form a narrow path across the reservoir. + +> n + +You are walking across the bottom of the reservoir. Walls of water +rear up on either side. The roar of the water cascading past is +nearly deafening, and the mist is so thick you can barely see. + +> n + +You are at the northern edge of the reservoir. A northwest passage +leads sharply up from here. + +The waters have parted to form a narrow path across the reservoir. + +> nw + +You are scrambling along a treacherously steep, rocky passage. + +> u + +You are on a very steep incline, which widens at it goes upward. + +> u + +You are at the base of a nearly vertical cliff. There are some +slim footholds which would enable you to climb up, but it looks +extremely dangerous. Here at the base of the cliff lie the remains +of several earlier adventurers who apparently failed to make it. + +> u + +You are climbing along a nearly vertical cliff. + +> u + +Just as you reach the top, your foot slips on a loose rock and you +make one last desperate grab. Your luck holds, as does your grip. +With an enormous heave, you lift yourself to the ledge above. + +You are on a small ledge at the top of a nearly vertical cliff. +There is a low crawl leading off to the northeast. + +> ne + +You have reached a dead end. + +There is a richly-carved ebony statuette here! + +> take ebony + +OK + +> sw + +You're at top of cliff. + +> d + +You are climbing along a nearly vertical cliff. + +> d + +You're at base of cliff. + +> d + +You are on a very steep incline, which widens at it goes upward. + +> d + +You are scrambling along a treacherously steep, rocky passage. + +> se + +You're north of reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You're at bottom of reservoir. + +> s + +You're at reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> take water + +Your bottle is now full of water. + +> s + +You are in a north/south canyon about 25 feet across. The floor is +covered by white mist seeping in from the north. The walls extend +upward for well over 100 feet. Suspended from some unseen point far +above you, an enormous two-sided mirror is hanging parallel to and +midway between the canyon walls. (The mirror is obviously provided +for the use of the dwarves who, as you know, are extremely vain.) A +small window can be seen in either wall, some fifty feet up. + +> s + +You are in a secret n/s canyon above a large room. + +> d + +You're in Slab Room. + +> s + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> water plant + +The plant grows explosively, almost filling the bottom of the pit. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> e + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the eastern pit in the Twopit Room. There is +a small pool of oil in one corner of the pit. + +> take oil + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You are in a long, narrow corridor stretching out of sight to the +west. At the eastern end is a hole through which you can see a +profusion of leaves. + +> w + +You are in the Giant Room. The ceiling here is too high up for your +lamp to show it. Cavernous passages lead east, north, and south. On +the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. + +There is a large nest here, full of golden eggs! + +> n + +You are at one end of an immense north/south passage. + +The way north is barred by a massive, rusty, iron door. + +> oil door + +The oil has freed up the hinges so that the door will now move, +although it requires some effort. + +> n + +You are in a magnificent cavern with a rushing stream, which cascades +over a sparkling waterfall into a roaring whirlpool which disappears +through a hole in the floor. Passages exit to the south and west. + +There is a jewel-encrusted trident here! + +> take trident + +OK + +> w + +You are at the top of a steep incline above a large room. You could +climb down here, but you would not be able to climb up. There is a +passage leading back to the north. + +> d + +You are in a large low room. Crawls lead north, se, and sw. + +> se + +This is the Oriental Room. Ancient oriental cave drawings cover the +walls. A gently sloping passage leads upward to the north, another +passage leads se, and a hands and knees crawl leads west. + +There is a delicate, precious, ming vase here! + +> n + +You are following a wide path around the outer edge of a large cavern. +Far below, through a heavy white mist, strange splashing noises can be +heard. The mist rises up through a fissure in the ceiling. The path +exits to the south and west. + +> w + +You are in an alcove. A small nw path seems to widen after a short +distance. An extremely tight tunnel leads east. It looks like a very +tight squeeze. An eerie light can be seen at the other end. + +> drop trident + +OK + +> drop axe + +OK + +> drop ebony + +OK + +> drop bottle + +OK + +> drop appendage + +OK + +> drop lamp + +OK + +> e + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> take emerald + +OK + +> w + +You're in alcove. + +There is a lamp shining nearby. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is an empty bottle here. + +There is a richly-carved ebony statuette here! + +There is a little axe here. + +There is a jewel-encrusted trident here! + +> take lamp + +OK + +> take bottle + +OK + +> take ebony + +OK + +> take axe + +OK + +> take trident + +OK + +> nw + +You're in misty cavern. + +> s + +You're in Oriental Room. + +There is a delicate, precious, ming vase here! + +> take vase + +OK + +> e + +There is no way to go that direction. + +You're in Oriental Room. + +> se + +You are in a room whose walls resemble swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> e + +You are in the Soft Room. The walls are covered with heavy curtains, +the floor with a thick pile carpet. Moss covers the ceiling. + +A small velvet pillow lies on the floor. + +> take pillow + +You can't carry anything more. You'll have to drop something first. + +> w + +You're in Swiss Cheese Room. + +> ne + +You're in Bedquilt. + +> e + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> n + +You're in a large room carved out of sedimentary rock. The floor and +walls are littered with bits of shells imbedded in the stone. A +shallow passage proceeds downward, and a somewhat steeper one leads +up. A low hands and knees passage enters from the south. + +There is an enormous clam here with its shell tightly closed. + +> open clam + +A glistening pearl falls out of the clam and rolls away. Goodness, +this must really be an oyster. (I never was very good at identifying +bivalves.) Whatever it is, it has now snapped shut again. + +> s + +You're at complex junction. + +> u + +You are in a large room full of dusty rocks. There is a big hole in +the floor. There are cracks everywhere, and a passage leading east. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're at "Y2". + +> plugh + +>>Foof!<< + +You are inside a building, a well house for a large spring. + +There is an enormous ruby here! + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There is a persian rug spread out on the floor! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are bars of silver here! + +There are some keys on the ground here. + +There is food here. + +> drop pillow + +I see no pillow here. + +> drop vase + +The ming vase drops with a delicate crash. + +> drop trident + +OK + +> drop ebony + +OK + +> drop emerald + +OK + +> take food + +OK + +> take keys + +OK + +> plugh + +>>Foof!<< + +You're at "Y2". + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +> w + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You are in the Hall of the Mountain King, with passages off in all +directions. + +> n + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> d + +You're in dirty passage. + +> w + +You're in dusty rock room. + +> d + +You're at complex junction. + +> n + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> d + +You are in a long sloping corridor with ragged sharp walls. + +> d + +You are in a cul-de-sac about eight feet across. + +Off to one side lies a glistening pearl! + +> take pearl + +OK + +> up + +You are in a long sloping corridor with ragged sharp walls. + +> u + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> s + +You're at complex junction. + +> w + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in Bedquilt. + +> throw axe + +You attack a little dwarf, but he dodges out of the way. + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in Bedquilt. + +There is a little axe here. + +> take axe + +OK + +> w + +There is a threatening little dwarf in the room with you! + +You're in Swiss Cheese Room. + +> throw axe + +You killed a little dwarf. + +You're in Swiss Cheese Room. + +There is a little axe here. + +> take axe + +OK + +> w + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> get oil + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +There is a large nest here, full of golden eggs! + +> get eggs + +You can't carry anything more. You'll have to drop something first. + +> drop coins + +OK + +> get eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +The way north leads through a massive, rusty, iron door. + +> n + +You're in cavern with waterfall. + +> d + +There is no way to go that direction. + +You're in cavern with waterfall. + +> w + +You're at steep incline above large room. + +> d + +You're in large low room. + +> sw + +You are in a long winding corridor sloping out of sight in both +directions. + +> up + +You are on one side of a large, deep chasm. A heavy white mist rising +up from below obscures all view of the far side. A sw path leads away +from the chasm into a winding corridor. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> toss eggs + +The troll catches your treasure and scurries away out of sight. + +> ne + +You are on the far side of the chasm. A ne path leads away from the +chasm on this side. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> ne + +You're in a long east/west corridor. A faint rumbling noise can be +heard in the distance. + +> barren + +You are standing at the entrance to a large, barren room. A notice +above the entrance reads: "Caution! Bear in room!" + +> in + +You are inside a barren room. The center of the room is completely +empty except for some dust. Marks in the dust lead away toward the +far end of the room. The only exit is the way you came in. + +There is a ferocious cave bear eying you from the far end of the room! + +The bear is locked to the wall with a golden chain! + +> feed bear + +The bear eagerly wolfs down your food, after which he seems to calm +down considerably and even becomes rather friendly. + +> unlock chain + +The chain is now unlocked. + +> take bear + +OK + +> w + +You are being followed by a very large, tame bear. + +You're in front of Barren Room. + +> fork + +You are being followed by a very large, tame bear. + +The path forks here. The left fork leads northeast. A dull rumbling +seems to get louder in that direction. The right fork leads southeast +down a gentle slope. The main corridor enters from the west. + +> ne + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> e + +You are being followed by a very large, tame bear. + +You are in a small chamber filled with large boulders. The walls are +very warm, causing the air in the room to be almost stifling from the +heat. The only exit is a crawl heading west, through which is coming +a low rumbling. + +There are rare spices here! + +> drop keys + +OK + +> take spices + +OK + +> fork + +You are being followed by a very large, tame bear. + +You're at fork in path. + +> w + +You are being followed by a very large, tame bear. + +You're in corridor. + +> w + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +The troll steps out from beneath the bridge and blocks your way. + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> free bear + +The bear lumbers toward the troll, who lets out a startled shriek and +scurries away. The bear soon gives up the pursuit and wanders back. + +> sw + +You're on sw side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +You're in sloping corridor. + +> d + +You're in large low room. + +> se + +You're in Oriental Room. + +> se + +You're in Swiss Cheese Room. + +> w + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> climb + +I don't know how to apply that word here. + +You're in east pit. + +> up + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +There are many coins here! + +> take coins + +OK + +> fee + +OK + +> fie + +OK + +> foe + +OK + +> foo + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> s + +You're in narrow corridor. + +> d + +Out from the shadows behind you pounces a bearded pirate! "Har, har," +he chortles, "I'll just take all this booty and hide it away with me +chest deep in the maze!" He snatches your treasure and vanishes into +the gloom. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're in Slab Room. + +> u + +You are in a secret n/s canyon above a large room. + +> s + +You are in a secret canyon which exits to the north and east. + +The body of a huge green dead dragon is lying off to one side. + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +There is a threatening little dwarf in the room with you! + +You're in Hall of Mt King. + +> e + +There is a threatening little dwarf in the room with you! + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> w + +Your lamp is getting dim. You'd best start wrapping this up, unless +you can find some fresh batteries. I seem to recall there's a vending +machine in the maze. Bring some coins with you. + +There is a threatening little dwarf in the room with you! + +You're on east bank of fissure. + +There is a small wicker cage discarded nearby. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge now spans the fissure. + +> w + +There is a threatening little dwarf in the room with you! + +You're on west bank of fissure. + +A crystal bridge now spans the fissure. + +> w + +There is a threatening little dwarf in the room with you! + +You're at west end of Hall of Mists. + +> throw axe + +You killed a little dwarf. + +You're at west end of Hall of Mists. + +There is a little axe here. + +> take axe + +OK + +> w + +You're at east end of long hall. + +> w + +You're at west end of long hall. + +> s + +You are in a maze of twisty little passages, all different. + +> sw + +You are in a little maze of twisty passages, all different. + +> se + +You are in a little maze of twisting passages, all different. + +> s + +Dead end + +There is a message scrawled in the dust in a flowery script, reading: +"This is not the maze where the pirate leaves his treasure chest." + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> +You scored 219 out of a possible 430, using 313 turns. + +You may now consider yourself a "Seasoned Adventurer". + +To achieve the next higher rating, you need 32 more points. From c3bb0dae7503b5c059b3b199137503840bf6f30b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 14 Mar 2023 10:48:53 -0400 Subject: [PATCH 18/23] Quiet down database compilation. Observe RNG stability. At this commit, we can tell that the seeded-RNG nehavopr of this 430 branch is identical to that of master because the axebear log - which includes randomization of dwarf spawning and the reservoir word - yields the same results in both versions. --- init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init.c b/init.c index a74dd86..9cdbeef 100644 --- a/init.c +++ b/init.c @@ -180,7 +180,7 @@ void initialise(void) { } static int raw_init(void) { - printf("Couldn't find adventure.data, using adventure.text...\n"); + //printf("Couldn't find adventure.data, using adventure.text...\n"); FILE *OPENED=fopen("adventure.text","r" /* NOT binary */); if(!OPENED){printf("Can't read adventure.text!\n"); exit(0);} @@ -634,7 +634,7 @@ L1993: SETPRM(1,LINUSE,LINSIZ); SETPRM(15,CLSSES,CLSMAX); SETPRM(17,HNTMAX,HNTSIZ); SETPRM(19,TRNVLS,TRNSIZ); - RSPEAK(267); + //RSPEAK(267); TYPE0(); } @@ -661,7 +661,7 @@ static bool quick_init(void) { } static void quick_save(void) { - printf("Writing adventure.data...\n"); + //printf("Writing adventure.data...\n"); f = fopen("adventure.data",WRITE_MODE); if(f == NULL){printf("Can't open file!\n"); return;} init_reading = false; From 0a63b5e2d6282aae6f6952b5247a319a1030b7c7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 12:30:39 -0400 Subject: [PATCH 19/23] Trim resume file names as required. --- misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc.c b/misc.c index 9e18c74..0725ab5 100644 --- a/misc.c +++ b/misc.c @@ -994,6 +994,8 @@ L10: fclose(F); L20: printf("\nFile name: "); IGNORE(fgets(NAME, sizeof(NAME), stdin)); + if (NAME[strlen(NAME)-1] == '\n') + NAME[strlen(NAME)-1] = '\0'; F=fopen(NAME,(IN ? READ_MODE : WRITE_MODE)); if(F == NULL) {printf("Can't open file, try again.\n"); goto L20;} return; From bed5fb747ba1c891c95032c2f4d30f1710bbe1cc Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 14:24:42 -0400 Subject: [PATCH 20/23] Don't loop back on resume file read failure... ...it's inconvenient for testing. --- misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 0725ab5..e717b3f 100644 --- a/misc.c +++ b/misc.c @@ -997,7 +997,7 @@ L20: printf("\nFile name: "); if (NAME[strlen(NAME)-1] == '\n') NAME[strlen(NAME)-1] = '\0'; F=fopen(NAME,(IN ? READ_MODE : WRITE_MODE)); - if(F == NULL) {printf("Can't open file, try again.\n"); goto L20;} + if(F == NULL) {printf("Can't open file, try again.\n"); /* goto L20; */} return; L30: if(IN)IGNORE(fread(ARR,sizeof(long),250,F)); From ffa9332ee3967f14f83621eb090521f9d43da14a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 15:05:31 -0400 Subject: [PATCH 21/23] Avoid noise diffs around logging of seed command. --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 398081d..558edcf 100644 --- a/main.c +++ b/main.c @@ -147,7 +147,7 @@ static bool fallback_handler(signed char *buf) long sv; if (sscanf(buf, "seed %ld", &sv) == 1) { set_seed(sv); - printf("Seed set to %ld\n", sv); + printf("\nSeed set to %ld\n", sv); // autogenerated, so don't charge user time for it. --TURNS; // here we reconfigure any global game state that uses random numbers From 286556f885b3cd617d30e8416882def5e5f3741a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 18:16:53 -0400 Subject: [PATCH 22/23] Make Z a synonym for NOTHI. --- adventure.text | 1 + 1 file changed, 1 insertion(+) diff --git a/adventure.text b/adventure.text index 5ec4034..97a0fdf 100644 --- a/adventure.text +++ b/adventure.text @@ -1292,6 +1292,7 @@ 2004 UNLOC 2004 OPEN 2005 NOTHI +2005 Z 2006 LOCK 2006 CLOSE 2007 LIGHT From d388877c1b1eea7df89c4a688f7de5c118d59f4b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 16:18:34 -0400 Subject: [PATCH 23/23] Implement -d option. --- main.c | 6 +++++- main.h | 1 + misc.c | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 558edcf..bfc4a12 100644 --- a/main.c +++ b/main.c @@ -42,6 +42,7 @@ long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BO WZDARK = false, ZZWORD; FILE *logfp; bool oldstyle = false; +int debug; lcg_state lcgstate; extern void initialise(); @@ -67,8 +68,11 @@ int main(int argc, char *argv[]) { /* Options. */ - while ((ch = getopt(argc, argv, "l:o")) != EOF) { + while ((ch = getopt(argc, argv, "dl:o")) != EOF) { switch (ch) { + case 'd': + debug += 1; + break; case 'l': logfp = fopen(optarg, "w+"); if (logfp == NULL) diff --git a/main.h b/main.h index 184acee..8489fa4 100644 --- a/main.h +++ b/main.h @@ -13,4 +13,5 @@ extern long ABB[], ATAB[], ATLOC[], BLKLIN, DFLAG, DLOC[], FIXED[], HOLDNG, extern signed char rawbuf[LINESIZE], INLINE[LINESIZE+1], MAP1[], MAP2[]; extern FILE *logfp; extern bool oldstyle; +extern int debug; extern lcg_state lcgstate; diff --git a/misc.c b/misc.c index e717b3f..4ee0f2b 100644 --- a/misc.c +++ b/misc.c @@ -770,6 +770,9 @@ unsigned long get_next_lcg_value(void) /* Return the LCG's current value, and then iterate it. */ unsigned long old_x = lcgstate.x; lcgstate.x = (lcgstate.a * lcgstate.x + lcgstate.c) % lcgstate.m; + if (debug) { + printf("# random %lu\n", old_x); + } return(old_x); }