Revert SEED handling and comment orocessing. It broke database compilation.

This code is remarkably like the game it implements - a maze of twisty
little FORTRANisms, all alike.  Very easy to get lost.
This commit is contained in:
Eric S. Raymond 2017-05-24 18:24:09 -04:00
parent 44e7ddc2ed
commit 31837249f8
6 changed files with 50 additions and 80 deletions

View file

@ -65,7 +65,6 @@ L4000: VERB=K;
case 31: goto L8320; /* FLY */ case 31: goto L8320; /* FLY */
case 32: goto L8330; /* LISTEN */ case 32: goto L8330; /* LISTEN */
case 33: goto L8340; /* ZZZZ */ case 33: goto L8340; /* ZZZZ */
case 34: goto L8350; /* SEED */
} }
BUG(23); BUG(23);
@ -106,7 +105,6 @@ L4090: switch (VERB-1) {
case 31: goto L9320; /* FLY */ case 31: goto L9320; /* FLY */
case 32: return(2011); /* LISTEN */ case 32: return(2011); /* LISTEN */
case 33: goto L8340; /* ZZZZ */ case 33: goto L8340; /* ZZZZ */
case 34: goto L8350; /* SEED */
} }
BUG(24); BUG(24);
@ -625,14 +623,4 @@ L8340: if(!AT(RESER) && LOC != FIXED[RESER]-1) return(2011);
RSPEAK(241); RSPEAK(241);
return(2); return(2);
/* Seed. Expected in game logs to replicate the LCG state */
L8350: {
long sv;
int n;
n = sscanf(raw_input, "seed %ld\n", &sv);
if (n >= 1)
set_seed(sv);
return(2);
}
} }

View file

@ -1358,7 +1358,6 @@
2032 FLY 2032 FLY
2033 LISTE 2033 LISTE
2034 Z'ZZZ (GETS REPLACED) 2034 Z'ZZZ (GETS REPLACED)
2035 SEED (USED IN REPLAY LOGS, NOT INTENDED FOR PLAYER)
3001 FEE 3001 FEE
3002 FIE 3002 FIE
3003 FOE 3003 FOE

63
main.c
View file

@ -7,7 +7,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <getopt.h> #include <getopt.h>
#include <string.h>
#include "main.h" #include "main.h"
#include "misc.h" #include "misc.h"
@ -18,7 +17,6 @@ long ABB[186], ATAB[331], ATLOC[186], BLKLIN = true, DFLAG,
PARMS[26], PLACE[101], PTEXT[101], RTEXT[278], PARMS[26], PLACE[101], PTEXT[101], RTEXT[278],
SETUP = 0, TABSIZ = 330; SETUP = 0, TABSIZ = 330;
signed char INLINE[LINESIZE+1], MAP1[129], MAP2[129]; signed char INLINE[LINESIZE+1], MAP1[129], MAP2[129];
signed char raw_input[LINESIZE+1];
long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BONUS, long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BONUS,
BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2,
@ -54,11 +52,10 @@ extern int action(FILE *, long);
* MAIN PROGRAM * MAIN PROGRAM
*/ */
static bool do_command(FILE *); static void do_command(FILE *);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int ch; int ch;
time_t starttime = time(NULL);
/* Adventure (rev 2: 20 treasures) */ /* Adventure (rev 2: 20 treasures) */
@ -73,7 +70,7 @@ int main(int argc, char *argv[]) {
while ((ch = getopt(argc, argv, "l:o")) != EOF) { while ((ch = getopt(argc, argv, "l:o")) != EOF) {
switch (ch) { switch (ch) {
case 'l': case 'l':
logfp = fopen(optarg, "w"); logfp = fopen(optarg, "w+");
if (logfp == NULL) if (logfp == NULL)
fprintf(stderr, fprintf(stderr,
"advent: can't open logfile %s for write\n", "advent: can't open logfile %s for write\n",
@ -102,7 +99,7 @@ int main(int argc, char *argv[]) {
lcgstate.a = 1093; lcgstate.a = 1093;
lcgstate.c = 221587; lcgstate.c = 221587;
lcgstate.m = 1048576; lcgstate.m = 1048576;
set_seed((long)starttime); set_seed_from_time();
/* Read the database if we have not yet done so */ /* Read the database if we have not yet done so */
@ -135,16 +132,12 @@ L1: SETUP= -1;
LIMIT=330; LIMIT=330;
if(NOVICE)LIMIT=1000; if(NOVICE)LIMIT=1000;
if (logfp)
fprintf(logfp, "seed %ld\n", starttime);
for (;;) { for (;;) {
if (!do_command(stdin)) do_command(stdin);
break;
} }
score(1);
} }
static bool do_command(FILE *cmdin) { static void do_command(FILE *cmdin) {
/* Can't leave cave once it's closing (except by main office). */ /* Can't leave cave once it's closing (except by main office). */
@ -396,8 +389,7 @@ L2603: if(!CLOSED) goto L2605;
L2605: WZDARK=DARK(0); L2605: WZDARK=DARK(0);
if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0; if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0;
I=0; I=0;
if (!GETIN(cmdin, WD1,WD1X,WD2,WD2X)) GETIN(cmdin, WD1,WD1X,WD2,WD2X);
return false;
/* Every input, check "FOOBAR" flag. If zero, nothing's going on. If pos, /* 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. */ * make neg. If neg, he skipped a word, so make it zero. */
@ -456,19 +448,8 @@ L2800: WD1=WD2;
/* Gee, I don't understand. */ /* Gee, I don't understand. */
L3000: SETPRM(1,WD1,WD1X); L3000: SETPRM(1,WD1,WD1X);
/* This is a kludge. The command parser we inherited from the base 2.5
* barfs on numeric tokens. It will fall through to here when it sees
* seed NNNN. Instead of barfing, go straight to the action processor
* where it will examine the raw input. This will fo away when we get
* rid of the obfuscated FORTRANoid input processing.
*/
if (strncmp(raw_input, "seed", 4) == 0) {
I=4090; K=34;
goto Laction;
} else {
RSPEAK(254); RSPEAK(254);
goto L2600; goto L2600;
}
/* Verb and object analysis moved to separate module. */ /* Verb and object analysis moved to separate module. */
@ -477,7 +458,7 @@ L4090: I=4090; goto Laction;
L5000: I=5000; L5000: I=5000;
Laction: Laction:
switch (action(cmdin, I)) { switch (action(cmdin, I)) {
case 2: return true; case 2: return;
case 8: goto L8; case 8: goto L8;
case 2000: goto L2000; case 2000: goto L2000;
case 2009: goto L2009; case 2009: goto L2009;
@ -513,7 +494,7 @@ L8000: SETPRM(1,WD1,WD1X);
L8: KK=KEY[LOC]; L8: KK=KEY[LOC];
NEWLOC=LOC; NEWLOC=LOC;
if(KK == 0)BUG(26); if(KK == 0)BUG(26);
if(K == NUL) return true; if(K == NUL) return;
if(K == BACK) goto L20; if(K == BACK) goto L20;
if(K == LOOK) goto L30; if(K == LOOK) goto L30;
if(K == CAVE) goto L40; if(K == CAVE) goto L40;
@ -544,11 +525,11 @@ L13: if(NEWLOC <= 100) goto L14;
L14: if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12; L14: if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12;
L16: NEWLOC=MOD(LL,1000); L16: NEWLOC=MOD(LL,1000);
if(NEWLOC <= 300) return true; if(NEWLOC <= 300) return;
if(NEWLOC <= 500) goto L30000; if(NEWLOC <= 500) goto L30000;
RSPEAK(NEWLOC-500); RSPEAK(NEWLOC-500);
NEWLOC=LOC; NEWLOC=LOC;
return true; return;
/* Special motions come here. Labelling convention: statement numbers NNNXX /* Special motions come here. Labelling convention: statement numbers NNNXX
* (XX=00-99) are used for special case number NNN (NNN=301-500). */ * (XX=00-99) are used for special case number NNN (NNN=301-500). */
@ -563,10 +544,10 @@ L30000: NEWLOC=NEWLOC-300;
* be used for actual motion, but can be spotted by "go back". */ * be used for actual motion, but can be spotted by "go back". */
L30100: NEWLOC=99+100-LOC; L30100: NEWLOC=99+100-LOC;
if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) return true; if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) return;
NEWLOC=LOC; NEWLOC=LOC;
RSPEAK(117); RSPEAK(117);
return true; return;
/* Travel 302. Plover transport. Drop the emerald (only use special travel if /* 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 * toting it), so he's forced to use the plover-passage to get it out. Having
@ -590,11 +571,11 @@ L30300: if(PROP[TROLL] != 1) goto L30310;
MOVE(TROLL+100,FIXD[TROLL]); MOVE(TROLL+100,FIXD[TROLL]);
JUGGLE(CHASM); JUGGLE(CHASM);
NEWLOC=LOC; NEWLOC=LOC;
return true; return;
L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC; L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC;
if(PROP[TROLL] == 0)PROP[TROLL]=1; if(PROP[TROLL] == 0)PROP[TROLL]=1;
if(!TOTING(BEAR)) return true; if(!TOTING(BEAR)) return;
RSPEAK(162); RSPEAK(162);
PROP[CHASM]=1; PROP[CHASM]=1;
PROP[TROLL]=2; PROP[TROLL]=2;
@ -618,7 +599,7 @@ L20: K=OLDLOC;
if(CNDBIT(LOC,4))K2=274; if(CNDBIT(LOC,4))K2=274;
if(K2 == 0) goto L21; if(K2 == 0) goto L21;
RSPEAK(K2); RSPEAK(K2);
return true; return;
L21: LL=MOD((IABS(TRAVEL[KK])/1000),1000); L21: LL=MOD((IABS(TRAVEL[KK])/1000),1000);
if(LL == K) goto L25; if(LL == K) goto L25;
@ -632,7 +613,7 @@ L22: if(TRAVEL[KK] < 0) goto L23;
L23: KK=K2; L23: KK=K2;
if(KK != 0) goto L25; if(KK != 0) goto L25;
RSPEAK(140); RSPEAK(140);
return true; return;
L25: K=MOD(IABS(TRAVEL[KK]),1000); L25: K=MOD(IABS(TRAVEL[KK]),1000);
KK=KEY[LOC]; KK=KEY[LOC];
@ -645,14 +626,14 @@ L30: if(DETAIL < 3)RSPEAK(15);
DETAIL=DETAIL+1; DETAIL=DETAIL+1;
WZDARK=false; WZDARK=false;
ABB[LOC]=0; ABB[LOC]=0;
return true; return;
/* Cave. Different messages depending on whether above ground. */ /* Cave. Different messages depending on whether above ground. */
L40: K=58; L40: K=58;
if(OUTSID(LOC) && LOC != 8)K=57; if(OUTSID(LOC) && LOC != 8)K=57;
RSPEAK(K); RSPEAK(K);
return true; return;
/* Non-applicable motion. Various messages depending on word given. */ /* Non-applicable motion. Various messages depending on word given. */
@ -665,7 +646,11 @@ L50: SPK=12;
if(K == 62 || K == 65)SPK=42; if(K == 62 || K == 65)SPK=42;
if(K == 17)SPK=80; if(K == 17)SPK=80;
RSPEAK(SPK); RSPEAK(SPK);
return true; return;
/* "You're dead, Jim." /* "You're dead, Jim."
* *
@ -879,7 +864,7 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
RSPEAK(132); RSPEAK(132);
CLOSED=true; CLOSED=true;
return true; return;
/* Another way we can force an end to things is by having the lamp give out. /* 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 * When it gets close, we come here to warn him. We go to 12000 if the lamp

1
main.h
View file

@ -11,7 +11,6 @@ extern long ABB[], ATAB[], ATLOC[], BLKLIN, DFLAG, DLOC[], FIXED[], HOLDNG,
KTAB[], *LINES, LINK[], LNLENG, LNPOSN, KTAB[], *LINES, LINK[], LNLENG, LNPOSN,
PARMS[], PLACE[], PTEXT[], RTEXT[], TABSIZ; PARMS[], PLACE[], PTEXT[], RTEXT[], TABSIZ;
extern signed char INLINE[LINESIZE+1], MAP1[], MAP2[]; extern signed char INLINE[LINESIZE+1], MAP1[], MAP2[];
extern signed char raw_input[LINESIZE+1];
extern FILE *logfp; extern FILE *logfp;
extern bool oldstyle; extern bool oldstyle;
extern lcg_state lcgstate; extern lcg_state lcgstate;

40
misc.c
View file

@ -173,7 +173,7 @@ void fSETPRM(long FIRST, long P1, long P2) {
#define WORD1X (*wORD1X) #define WORD1X (*wORD1X)
#define WORD2 (*wORD2) #define WORD2 (*wORD2)
#define WORD2X (*wORD2X) #define WORD2X (*wORD2X)
bool fGETIN(FILE *input, long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) { void fGETIN(FILE *input, long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) {
long JUNK; long JUNK;
/* Get a command from the adventurer. Snarf out the first word, pad it with /* Get a command from the adventurer. Snarf out the first word, pad it with
@ -185,8 +185,7 @@ long JUNK;
L10: if(BLKLIN)TYPE0(); L10: if(BLKLIN)TYPE0();
MAPLIN(input); MAPLIN(input);
if (feof(input)) if(input == stdin && feof(stdin)) score(1);
return false;
WORD1=GETTXT(true,true,true,0); WORD1=GETTXT(true,true,true,0);
if(BLKLIN && WORD1 < 0) goto L10; if(BLKLIN && WORD1 < 0) goto L10;
WORD1X=GETTXT(false,true,true,0); WORD1X=GETTXT(false,true,true,0);
@ -196,7 +195,7 @@ L12: JUNK=GETTXT(false,true,true,0);
WORD2X=GETTXT(false,true,true,0); WORD2X=GETTXT(false,true,true,0);
L22: JUNK=GETTXT(false,true,true,0); L22: JUNK=GETTXT(false,true,true,0);
if(JUNK > 0) goto L22; if(JUNK > 0) goto L22;
if(GETTXT(true,true,true,0) <= 0)return true; if(GETTXT(true,true,true,0) <= 0)return;
RSPEAK(53); RSPEAK(53);
goto L10; goto L10;
} }
@ -724,7 +723,7 @@ L2: ATDWRF=I;
/* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value, randrange, RNDVOC, BUG) */ /* Utility routines (SETBIT, TSTBIT, set_seed_from_time, get_next_lcg_value, randrange, RNDVOC, BUG) */
#undef SETBIT #undef SETBIT
long fSETBIT(long BIT) { long fSETBIT(long BIT) {
@ -759,9 +758,11 @@ long TSTBIT;
#define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT) #define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT)
void set_seed(long seedval) void set_seed_from_time(void)
{ {
lcgstate.x = (unsigned long) seedval % lcgstate.m; /* 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;
} }
unsigned long get_next_lcg_value(void) unsigned long get_next_lcg_value(void)
@ -854,7 +855,7 @@ void fBUG(long NUM) {
#define BUG(NUM) fBUG(NUM) #define BUG(NUM) fBUG(NUM)
#undef MAPLIN #undef MAPLIN
void fMAPLIN(FILE *OPENED) { void fMAPLIN(FILE *OPENED) {
signed char *cp; long I, VAL;
/* Read a line of input, from the specified input source, /* Read a line of input, from the specified input source,
* translate the chars to integers in the range 0-126 and store * translate the chars to integers in the range 0-126 and store
@ -883,24 +884,23 @@ void fMAPLIN(FILE *OPENED) {
if(MAP2[1] == 0)MPINIT(); if(MAP2[1] == 0)MPINIT();
if (!oldstyle && SETUP && OPENED == stdin) if (!oldstyle && SETUP)
fputs("> ", stdout); fputs("> ", stdout);
do { IGNORE(fgets(INLINE+1,sizeof(INLINE)-1,OPENED));
IGNORE(fgets(raw_input,sizeof(INLINE)-1,OPENED));
} while
/* allow comments in logfiles */
(!feof(OPENED) && raw_input[0] == '#');
if (feof(OPENED)) { if (feof(OPENED)) {
if (logfp && OPENED == stdin) if (logfp)
fclose(logfp); fclose(logfp);
} else { } else {
if (logfp) if (logfp)
IGNORE(fputs(raw_input, logfp)); IGNORE(fputs(INLINE+1, logfp));
else if (!isatty(0)) else if (!isatty(0))
IGNORE(fputs(raw_input, stdout)); IGNORE(fputs(INLINE+1, stdout));
for (cp = raw_input; *cp; cp++) LNLENG=0;
INLINE[cp - raw_input + 1]=MAP1[*cp + 1]; for (I=1; I<=sizeof(INLINE) && INLINE[I]!=0; I++) {
LNLENG = (cp - raw_input); VAL=INLINE[I]+1;
INLINE[I]=MAP1[VAL];
if(INLINE[I] != 0)LNLENG=I;
} /* end loop */
LNPOSN=1; LNPOSN=1;
} }
} }

5
misc.h
View file

@ -1,6 +1,5 @@
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
/* b is not needed for POSIX but harmless */ /* b is not needed for POSIX but harmless */
#define READ_MODE "rb" #define READ_MODE "rb"
@ -14,7 +13,7 @@ extern void fRSPEAK(long);
#define RSPEAK(I) fRSPEAK(I) #define RSPEAK(I) fRSPEAK(I)
extern void fSETPRM(long,long,long); extern void fSETPRM(long,long,long);
#define SETPRM(FIRST,P1,P2) fSETPRM(FIRST,P1,P2) #define SETPRM(FIRST,P1,P2) fSETPRM(FIRST,P1,P2)
extern bool fGETIN(FILE *,long*,long*,long*,long*); extern void fGETIN(FILE *,long*,long*,long*,long*);
#define GETIN(input,WORD1,WORD1X,WORD2,WORD2X) fGETIN(input,&WORD1,&WORD1X,&WORD2,&WORD2X) #define GETIN(input,WORD1,WORD1X,WORD2,WORD2X) fGETIN(input,&WORD1,&WORD1X,&WORD2,&WORD2X)
extern long fYES(FILE *,long,long,long); extern long fYES(FILE *,long,long,long);
#define YES(input,X,Y,Z) fYES(input,X,Y,Z) #define YES(input,X,Y,Z) fYES(input,X,Y,Z)
@ -73,6 +72,6 @@ extern long fIABS(long);
#define IABS(N) fIABS(N) #define IABS(N) fIABS(N)
extern long fMOD(long,long); extern long fMOD(long,long);
#define MOD(N,M) fMOD(N,M) #define MOD(N,M) fMOD(N,M)
extern void set_seed(long); extern void set_seed_from_time(void);
extern unsigned long get_next_lcg_value(void); extern unsigned long get_next_lcg_value(void);
extern long randrange(long); extern long randrange(long);