X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=main.c;h=5a3f2002683de89e3c78aad525adb756b0a447a0;hb=70b5b191fd43dfe3f2e4661c3ea6b27e037625b5;hp=95e69732457947eaa61cb891c1068b5cd3f0e4c1;hpb=3bdab31a0d0c8c7397be835cf97bbf4d5a1c97de;p=open-adventure.git diff --git a/main.c b/main.c index 95e6973..5a3f200 100644 --- a/main.c +++ b/main.c @@ -3,15 +3,15 @@ * * The author - Don Woods - apologises for the style of the code; it * is a result of running the original Fortran IV source through a - * home-brew Fortran-to-C converter.) + * home-brew Fortran-to-C converter. * * Now that the code has been restructured into something much closer * to idiomatic C, the following is more appropriate: * - * ESR apologizes for the remaing gotos (now confined to two functions - * in this file - there used to be hundreds of them, *everywhere*), - * and the offensive globals. Applying the Structured Program Theorem - * can be hard. + * ESR apologizes for the remaing gotos (now confined to one function + * in this file - there used to be over 350 of them, *everywhere*), + * and for the offensive globals. Applying the Structured Program + * Theorem can be hard. */ #include #include @@ -122,20 +122,9 @@ int main(int argc, char *argv[]) set_seed(seedval); /* Initialize game variables */ - if (!game.setup) - initialise(); - - /* 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); - exit(0); - } + initialise(); /* Start-up, dwarf stuff */ - game.setup= -1; game.zzword=RNDVOC(3,0); game.novice=YES(stdin, 65,1,0); game.newloc=1; @@ -146,7 +135,7 @@ int main(int argc, char *argv[]) if (logfp) fprintf(logfp, "seed %ld\n", seedval); - /* interpret commands ubtil EOF or interrupt */ + /* interpret commands until EOF or interrupt */ for (;;) { if (!do_command(stdin)) break; @@ -267,6 +256,65 @@ static void checkhints(FILE *cmdin) } } +bool spotted_by_pirate(int i) +{ + if (i != PIRATE) + return false; + + /* The pirate's spotted him. He leaves him alone once we've + * found chest. K counts if a treasure is here. If not, and + * tally=1 for an unseen chest, let the pirate be spotted. + * Note that game.place[CHEST]=0 might mean that he's thrown + * it to the troll, but in that case he's seen the chest + * (game.prop=0). */ + if (game.loc == game.chloc || game.prop[CHEST] >= 0) + return true; + int k=0; + for (int j=MINTRS; j<=MAXTRS; j++) { + /* Pirate won't take pyramid from plover room or dark + * room (too easy!). */ + if (j==PYRAM && (game.loc==PLAC[PYRAM] || game.loc==PLAC[EMRALD])) { + return true; + } + if (TOTING(j)) { + if (game.place[CHEST] == 0) { + /* Install chest only once, to insure it is + * the last treasure in the list. */ + MOVE(CHEST,game.chloc); + MOVE(MESSAG,game.chloc2); + } + RSPEAK(128); + for (int j=MINTRS; j<=MAXTRS; j++) { + if (!(j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) { + if (AT(j) && game.fixed[j] == 0) + CARRY(j,game.loc); + if (TOTING(j)) + DROP(j,game.chloc); + } + } + game.dloc[PIRATE]=game.chloc; + game.odloc[PIRATE]=game.chloc; + game.dseen[PIRATE]=false; + return true; + } + if (HERE(j)) + k=1; + } + /* Force chest placement before player finds last treasure */ + if (game.tally == 1 && k == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) { + RSPEAK(186); + MOVE(CHEST,game.chloc); + MOVE(MESSAG,game.chloc2); + game.dloc[PIRATE]=game.chloc; + game.odloc[PIRATE]=game.chloc; + game.dseen[PIRATE]=false; + return true; + } + if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20)) + RSPEAK(127); + return true; +} + static bool dwarfmove(void) /* Dwarves move. Return true if player survives, false if he dies. */ { @@ -328,7 +376,6 @@ static bool dwarfmove(void) attack=0; stick=0; for (int i=1; i<=NDWARVES; i++) { - int k; if (game.dloc[i] == 0) continue; /* Fill TK array with all the places this dwarf might go. */ @@ -362,67 +409,8 @@ static bool dwarfmove(void) game.dseen[i]=(game.dseen[i] && INDEEP(game.loc)) || (game.dloc[i] == game.loc || game.odloc[i] == game.loc); if (!game.dseen[i]) continue; game.dloc[i]=game.loc; - if (i == PIRATE) { - /* The pirate's spotted him. He leaves him alone once we've - * found chest. K counts if a treasure is here. If not, and - * tally=1 for an unseen chest, let the pirate be spotted. - * Note that game.place(CHEST)=0 might mean that he's thrown - * it to the troll, but in that case he's seen the chest - * (game.prop=0). */ - if (game.loc == game.chloc || game.prop[CHEST] >= 0) - continue; - k=0; - for (int j=MINTRS; j<=MAXTRS; j++) { - /* Pirate won't take pyramid from plover room or dark - * room (too easy!). */ - if (j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD])) { - if (HERE(j)) - k=1; - continue; - } - if (TOTING(j)) { - if (game.place[CHEST] == 0) { - /* Install chest only once, to insure it is - * the last treasure in the list. */ - MOVE(CHEST,game.chloc); - MOVE(MESSAG,game.chloc2); - } - RSPEAK(128); - for (int j=MINTRS; j<=MAXTRS; j++) { - if (!(j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) { - if (AT(j) && game.fixed[j] == 0) - CARRY(j,game.loc); - if (TOTING(j)) - DROP(j,game.chloc); - } - } - game.dloc[PIRATE]=game.chloc; - game.odloc[PIRATE]=game.chloc; - game.dseen[PIRATE]=false; - /* C doesn't have what the Structured rogramming - * Theorem says we need here - multi-level loop - * breakout. We simulate with a goto. Irreducible, alas. - */ - goto jumpout; - } - if (HERE(j)) - k=1; - } - /* Force chest placement before player finds last treasure */ - if (game.tally == 1 && k == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) { - RSPEAK(186); - MOVE(CHEST,game.chloc); - MOVE(MESSAG,game.chloc2); - game.dloc[PIRATE]=game.chloc; - game.odloc[PIRATE]=game.chloc; - game.dseen[PIRATE]=false; - continue; - } - if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20)) - RSPEAK(127); + if (spotted_by_pirate(i)) continue; - } - /* This threatening little dwarf is in the room with him! */ ++game.dtotal; if (game.odloc[i] == game.dloc[i]) { @@ -432,7 +420,6 @@ static bool dwarfmove(void) if (randrange(1000) < 95*(game.dflag-2)) ++stick; } - jumpout:; } /* Now we know what's happening. Let's tell the poor sucker about it. @@ -914,7 +901,7 @@ static void listobjects(void) static bool do_command(FILE *cmdin) /* Get and execute a command */ { - long KQ, VERB, KK, V1, V2; + long KQ, VERB, V1, V2; long i, k, KMOD; static long igo = 0; static long obj = 0; @@ -1026,15 +1013,12 @@ static bool do_command(FILE *cmdin) part=transitive; goto Laction; } - if (closecheck()) + if (closecheck()) { if (game.closed) return true; - else - goto L19999; - - lampcheck(); + } else + lampcheck(); - L19999: k=43; if (LIQLOC(game.loc) == WATER)k=70; V1=VOCAB(WD1,-1);