X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=main.c;h=d11575613113e186e3b5eb37e5f99cd040f8bdf8;hp=a74aa6b2b44ca76b811910f1ecaca8e029b82bb6;hb=60ab7a63dc7c2b52bf21887f365a58588a08f708;hpb=66c22301edf3126e7525e1c52efdde8fb69e0257 diff --git a/main.c b/main.c index a74aa6b..d115756 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. + * 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 @@ -399,6 +399,10 @@ static bool dwarfmove(void) 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)) @@ -606,90 +610,104 @@ static bool playermove(FILE *cmdin, token_t verb, int motion) } LL=LL/1000; - for (;;) { - game.newloc=LL/1000; - motion=MOD(game.newloc,100); - if (game.newloc <= 300) { - if (game.newloc <= 100) { - if (game.newloc == 0 || PCT(game.newloc)) - break; + do { + /* + * (ESR) This special-travel loop may have to be repeated if it includes + * the plover passage. Same deal for any future cases wgerw we beed to + * block travel and then redo it once the blocking condition has been + * removed. + */ + for (;;) { + game.newloc=LL/1000; + motion=MOD(game.newloc,100); + if (game.newloc <= 300) { + if (game.newloc <= 100) { + if (game.newloc == 0 || PCT(game.newloc)) + break; + /* else fall through */ + } if (TOTING(motion) || (game.newloc > 200 && AT(motion))) + break; /* else fall through */ - } if (TOTING(motion) || (game.newloc > 200 && AT(motion))) - break; - /* else fall through */ + } + else if (game.prop[motion] != game.newloc/100-3) + break; + do { + if (TRAVEL[KK] < 0)BUG(25); + ++KK; + game.newloc=labs(TRAVEL[KK])/1000; + } while + (game.newloc == LL); + LL=game.newloc; } - else if (game.prop[motion] != game.newloc/100-3) - break; - L12: - do { - if (TRAVEL[KK] < 0)BUG(25); - ++KK; - game.newloc=labs(TRAVEL[KK])/1000; - } while - (game.newloc == LL); - LL=game.newloc; - } - game.newloc=MOD(LL,1000); - if (game.newloc <= 300) - return true; - if (game.newloc <= 500) { - game.newloc=game.newloc-300; - switch (game.newloc) - { - case 1: - /* Travel 301. Plover-alcove passage. Can carry only - * emerald. Note: travel table must include "useless" - * entries going through passage, which can never be used for - * actual motion, but can be spotted by "go back". */ - game.newloc=99+100-game.loc; - if (game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) - return true; - game.newloc=game.loc; - RSPEAK(117); + game.newloc=MOD(LL,1000); + if (game.newloc <= 300) return true; - case 2: - /* 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 dropped it, go back and - * pretend he wasn't carrying it after all. */ - DROP(EMRALD,game.loc); - goto L12; - case 3: - /* Travel 303. Troll bridge. Must be done only as special - * motion so that dwarves won't wander across and encounter - * the bear. (They won't follow the player there because - * that region is forbidden to the pirate.) If - * game.prop(TROLL)=1, he's crossed since paying, so step out - * and block him. (standard travel entries check for - * game.prop(TROLL)=0.) Special stuff for bear. */ - if (game.prop[TROLL] == 1) { - PSPEAK(TROLL,1); - game.prop[TROLL]=0; - MOVE(TROLL2,0); - MOVE(TROLL2+NOBJECTS,0); - MOVE(TROLL,PLAC[TROLL]); - MOVE(TROLL+NOBJECTS,FIXD[TROLL]); - JUGGLE(CHASM); + if (game.newloc <= 500) { + game.newloc=game.newloc-300; + switch (game.newloc) + { + case 1: + /* Travel 301. Plover-alcove passage. Can carry only + * emerald. Note: travel table must include "useless" + * entries going through passage, which can never be used for + * actual motion, but can be spotted by "go back". */ + game.newloc=99+100-game.loc; + if (game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) + return true; game.newloc=game.loc; + RSPEAK(117); return true; - } else { - game.newloc=PLAC[TROLL]+FIXD[TROLL]-game.loc; - if (game.prop[TROLL] == 0)game.prop[TROLL]=1; - if (!TOTING(BEAR)) return true; - RSPEAK(162); - game.prop[CHASM]=1; - game.prop[TROLL]=2; - DROP(BEAR,game.newloc); - game.fixed[BEAR]= -1; - game.prop[BEAR]=3; - game.oldlc2=game.newloc; - croak(cmdin); - return false; + case 2: + /* 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 dropped it, go back and + * pretend he wasn't carrying it after all. */ + DROP(EMRALD,game.loc); + do { + if (TRAVEL[KK] < 0)BUG(25); + ++KK; + game.newloc=labs(TRAVEL[KK])/1000; + } while + (game.newloc == LL); + continue; /* back to top of do/while loop */ + case 3: + /* Travel 303. Troll bridge. Must be done only as special + * motion so that dwarves won't wander across and encounter + * the bear. (They won't follow the player there because + * that region is forbidden to the pirate.) If + * game.prop(TROLL)=1, he's crossed since paying, so step out + * and block him. (standard travel entries check for + * game.prop(TROLL)=0.) Special stuff for bear. */ + if (game.prop[TROLL] == 1) { + PSPEAK(TROLL,1); + game.prop[TROLL]=0; + MOVE(TROLL2,0); + MOVE(TROLL2+NOBJECTS,0); + MOVE(TROLL,PLAC[TROLL]); + MOVE(TROLL+NOBJECTS,FIXD[TROLL]); + JUGGLE(CHASM); + game.newloc=game.loc; + return true; + } else { + game.newloc=PLAC[TROLL]+FIXD[TROLL]-game.loc; + if (game.prop[TROLL] == 0)game.prop[TROLL]=1; + if (!TOTING(BEAR)) return true; + RSPEAK(162); + game.prop[CHASM]=1; + game.prop[TROLL]=2; + DROP(BEAR,game.newloc); + game.fixed[BEAR]= -1; + game.prop[BEAR]=3; + game.oldlc2=game.newloc; + croak(cmdin); + return false; + } } + BUG(20); } - BUG(20); - } + } while + (false); RSPEAK(game.newloc-500); game.newloc=game.loc; return true; @@ -1008,15 +1026,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);