De-gotoifying main.c

This commit is contained in:
Eric S. Raymond 2017-06-08 05:01:51 -04:00
parent 8bf31a9c19
commit 30ac7894e7

217
main.c
View file

@ -47,91 +47,92 @@ void sig_handler(int signo)
/* /*
* MAIN PROGRAM * MAIN PROGRAM
*
* Adventure (rev 2: 20 treasures)
*
* History: Original idea & 5-treasure version (adventures) by Willie Crowther
* 15-treasure version (adventure) by Don Woods, April-June 1977
* 20-treasure version (rev 2) by Don Woods, August 1978
* Errata fixed: 78/12/25
* Revived 2017 as Open Advebture.
*/ */
static bool do_command(FILE *); static bool do_command(FILE *);
int main(int argc, char *argv[]) { int main(int argc, char *argv[])
int ch; {
int ch;
/* Adventure (rev 2: 20 treasures) */
/* History: Original idea & 5-treasure version (adventures) by Willie Crowther
* 15-treasure version (adventure) by Don Woods, April-June 1977
* 20-treasure version (rev 2) by Don Woods, August 1978
* Errata fixed: 78/12/25 */
/* Options. */ /* Options. */
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",
optarg); optarg);
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
break; break;
case 'o': case 'o':
oldstyle = true; oldstyle = true;
break; break;
}
} }
}
/* Logical variables: /* Logical variables:
* *
* game.closed says whether we're all the way closed * game.closed says whether we're all the way closed
* game.closng says whether it's closing time yet * game.closng says whether it's closing time yet
* game.clshnt says whether he's read the clue in the endgame * game.clshnt says whether he's read the clue in the endgame
* game.lmwarn says whether he's been warned about lamp going dim * game.lmwarn says whether he's been warned about lamp going dim
* game.novice says whether he asked for instructions at start-up * game.novice says whether he asked for instructions at start-up
* game.panic says whether he's found out he's trapped in the cave * game.panic says whether he's found out he's trapped in the cave
* game.wzdark says whether the loc he's leaving was dark */ * game.wzdark says whether the loc he's leaving was dark */
/* Initialize our LCG PRNG with parameters tested against Knuth vol. 2. by the original authors */ /* Initialize our LCG PRNG with parameters tested against
* Knuth vol. 2. by the original authors */
lcgstate.a = 1093;
lcgstate.c = 221587;
lcgstate.m = 1048576;
srand(time(NULL));
long seedval = (long)rand();
set_seed(seedval);
lcgstate.a = 1093; /* Initialize game variables */
lcgstate.c = 221587; MAP2[1] = 0;
lcgstate.m = 1048576; if (!game.setup)
srand(time(NULL)); initialise();
long seedval = (long)rand();
set_seed(seedval);
/* Read the database if we have not yet done so */
MAP2[1] = 0;
if (!game.setup)initialise();
if(game.setup > 0) goto L1;
/* Unlike earlier versions, adventure is no longer restartable. (This
* lets us get away with modifying things such as OBJSND(BIRD) without
* having to be able to undo the changes later.) If a "used" copy is
* rerun, we come here and tell the player to run a fresh copy. */
/* Unlike earlier versions, adventure is no longer restartable. (This
* lets us get away with modifying things such as OBJSND(BIRD) without
* having to be able to undo the changes later.) If a "used" copy is
* rerun, we come here and tell the player to run a fresh copy. */
if(game.setup <= 0) {
RSPEAK(201); RSPEAK(201);
exit(0); exit(0);
}
/* Start-up, dwarf stuff */ /* Start-up, dwarf stuff */
game.setup= -1;
game.zzword=RNDVOC(3,0);
game.novice=YES(stdin, 65,1,0);
game.newloc=1;
game.loc=1;
game.limit=330;
if(game.novice)game.limit=1000;
L1: game.setup= -1; if (logfp)
I=0; fprintf(logfp, "seed %ld\n", seedval);
game.zzword=RNDVOC(3,0);
game.novice=YES(stdin, 65,1,0);
game.newloc=1;
game.loc=1;
game.limit=330;
if(game.novice)game.limit=1000;
if (logfp) /* interpret commands ubtil EOF or interrupt */
fprintf(logfp, "seed %ld\n", seedval); for (;;) {
if (!do_command(stdin))
for (;;) { break;
if (!do_command(stdin)) }
break; /* show score and exit */
} score(1);
score(1);
} }
static bool fallback_handler(char *buf) static bool fallback_handler(char *buf)
@ -152,49 +153,57 @@ static bool fallback_handler(char *buf)
static bool do_command(FILE *cmdin) { static bool do_command(FILE *cmdin) {
long LL, KQ, VERB, KK, K2, V1, V2; long LL, KQ, VERB, KK, K2, V1, V2;
long obj; long obj, i;
long TK[21]; long TK[21];
static long IGO = 0; static long IGO = 0;
/* Can't leave cave once it's closing (except by main office). */ /* Can't leave cave once it's closing (except by main office). */
if(OUTSID(game.newloc) && game.newloc != 0 && game.closng) {
RSPEAK(130);
game.newloc=game.loc;
if(!game.panic)game.clock2=15;
game.panic=true;
}
if(!OUTSID(game.newloc) || game.newloc == 0 || !game.closng) goto L71; /* See if a dwarf has seen him and has come from where he
RSPEAK(130); * wants to go. If so, the dwarf's blocking his way. If
game.newloc=game.loc; * coming from place forbidden to pirate (dwarves rooted in
if(!game.panic)game.clock2=15; * place) let him get out (and attacked). */
game.panic=true; if(game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc,3)) {
for (i=1; i<=NDWARVES-1; i++) {
if(game.odloc[i] == game.newloc && game.dseen[i]) {
game.newloc=game.loc;
RSPEAK(2);
break;
}
}
}
game.loc=game.newloc;
/* See if a dwarf has seen him and has come from where he wants to go. If so, /* Dwarf stuff. See earlier comments for description of
* the dwarf's blocking his way. If coming from place forbidden to pirate * variables. Remember sixth dwarf is pirate and is thus
* (dwarves rooted in place) let him get out (and attacked). */ * very different except for motion rules. */
L71: if(game.newloc == game.loc || FORCED(game.loc) || CNDBIT(game.loc,3)) goto L74; /* First off, don't let the dwarves follow him into a pit or
/* 73 */ for (I=1; I<=NDWARVES-1; I++) { * a wall. Activate the whole mess the first time he gets as
if(game.odloc[I] != game.newloc || !game.dseen[I]) goto L73; * far as the hall of mists (loc 15). If game.newloc is
game.newloc=game.loc; * forbidden to pirate (in particular, if it's beyond the
RSPEAK(2); * troll bridge), bypass dwarf stuff. That way pirate can't
goto L74; * steal return toll, and dwarves can't meet the bear. Also
L73: /*etc*/ ; * means dwarves won't follow him into dead end in maze, but
} /* end loop */ * c'est la vie. They'll wait for him outside the dead
L74: game.loc=game.newloc; * end. */
if(game.loc == 0 || FORCED(game.loc) || CNDBIT(game.newloc,3))
goto L2000;
if(game.dflag != 0)
goto L6000;
if(INDEEP(game.loc))
game.dflag=1;
goto L2000;
/* Dwarf stuff. See earlier comments for description of variables. Remember /* When we encounter the first dwarf, we kill 0, 1, or 2 of
* sixth dwarf is pirate and is thus very different except for motion rules. */ * the 5 dwarves. If any of the survivors is at loc,
* replace him with the alternate. */
/* First off, don't let the dwarves follow him into a pit or a wall. Activate
* the whole mess the first time he gets as far as the hall of mists (loc 15).
* If game.newloc is forbidden to pirate (in particular, if it's beyond the troll
* bridge), bypass dwarf stuff. That way pirate can't steal return toll, and
* dwarves can't meet the bear. Also means dwarves won't follow him into dead
* end in maze, but c'est la vie. They'll wait for him outside the dead end. */
if(game.loc == 0 || FORCED(game.loc) || CNDBIT(game.newloc,3)) goto L2000;
if(game.dflag != 0) goto L6000;
if(INDEEP(game.loc))game.dflag=1;
goto L2000;
/* When we encounter the first dwarf, we kill 0, 1, or 2 of the 5 dwarves. If
* any of the survivors is at loc, replace him with the alternate. */
L6000: if(game.dflag != 1) goto L6010; L6000: if(game.dflag != 1) goto L6010;
if(!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc,4) || PCT(85)))) goto L2000; if(!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc,4) || PCT(85)))) goto L2000;