* and for the offensive globals. Applying the Structured Program
* Theorem can be hard.
*/
+#define DEFINE_GLOBALS_FROM_INCLUDES
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool oldstyle = false;
bool editline = true;
bool prompt = true;
-lcg_state lcgstate;
extern void initialise();
-extern void score(long);
extern int action(FILE *, long, long, long);
void sig_handler(int signo)
/* Initialize our LCG PRNG with parameters tested against
* Knuth vol. 2. by the original authors */
- lcgstate.a = 1093;
- lcgstate.c = 221587;
- lcgstate.m = 1048576;
+ game.lcg_a = 1093;
+ game.lcg_c = 221587;
+ game.lcg_m = 1048576;
srand(time(NULL));
long seedval = (long)rand();
set_seed(seedval);
/* Start-up, dwarf stuff */
game.zzword=RNDVOC(3,0);
- game.novice=YES(stdin, 65,1,0);
- game.newloc=1;
- game.loc=1;
+ game.novice=YES(stdin, WELCOME_YOU,CAVE_NEARBY,ARB_0);
+ game.newloc = LOC_START;
+ game.loc = LOC_START;
game.limit=330;
if (game.novice)game.limit=1000;
break;
}
/* show score and exit */
- score(1);
+ score(quitgame);
}
static bool fallback_handler(char *buf)
++game.hintlc[hint];
/* Come here if he's been long enough at required loc(s) for some
* unused hint. */
- if (game.hintlc[hint] >= HINTS[hint][1])
+ if (game.hintlc[hint] >= HINTS[hint][1])
{
int i;
/* Fall through to hint display */
game.hintlc[hint]=0;
- if (!YES(cmdin,HINTS[hint][3],0,54))
+ if (!YES(cmdin,HINTS[hint][3],ARB_0,OK_MAN))
return;
SETPRM(1,HINTS[hint][2],HINTS[hint][2]);
- RSPEAK(261);
- game.hinted[hint]=YES(cmdin,175,HINTS[hint][4],54);
- if (game.hinted[hint] && game.limit > 30)
- game.limit=game.limit+30*HINTS[hint][2];
+ RSPEAK(HINT_COST);
+ game.hinted[hint]=YES(cmdin,WANT_HINT,HINTS[hint][4],OK_MAN);
+ if (game.hinted[hint] && game.limit > WARNTIME)
+ game.limit += WARNTIME*HINTS[hint][2];
}
}
}
/* 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
+ * tally=1 for an unseen chest, let the pirate be spotted. Note
+ * that game.place[CHEST] = NOWHERE 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)
}
}
/* Force chest placement before player finds last treasure */
- if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) {
- RSPEAK(186);
+ if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == NOWHERE && HERE(LAMP) && game.prop[LAMP] == 1) {
+ RSPEAK(PIRATE_SPOTTED);
movechest = true;
}
/* Do things in this order (chest move before robbery) so chest is listed
/* You might get a hint of the pirate's presence even if the
* chest doesn't move... */
if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20))
- RSPEAK(127);
+ RSPEAK(PIRATE_RUSTLES);
}
if (robplayer) {
- RSPEAK(128);
+ RSPEAK(PIRATE_POUNCES);
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)
int kk, stick, attack;
long tk[21];
- /* Dwarf stuff. See earlier comments for description of
+ /* Dwarf stuff. See earlier comments for description of
* variables. Remember sixth dwarf is pirate and is thus
* very different except for motion rules. */
game.dloc[i]=DALTLC;
game.odloc[i]=game.dloc[i];
}
- RSPEAK(3);
+ RSPEAK(DWARF_RAN);
DROP(AXE,game.loc);
return true;
}
if (game.dtotal == 0)
return true;
SETPRM(1,game.dtotal,0);
- RSPEAK(4+1/game.dtotal);
+ RSPEAK(DWARF_PACK+1/game.dtotal); /* FIXME: Arithmetic on message number */
if (attack == 0)
return true;
if (game.dflag == 2)game.dflag=3;
SETPRM(1,attack,0);
int k=6;
- if (attack > 1)k=250;
+ if (attack > 1)k=THROWN_KNIVES;
RSPEAK(k);
SETPRM(1,stick,0);
- RSPEAK(k+1+2/(1+stick));
+ RSPEAK(k+1+2/(1+stick)); /* FIXME: Arithmetic on message number */
if (stick == 0)
return true;
game.oldlc2=game.loc;
if (game.closng) {
/* He died during closing time. No resurrection. Tally up a
* death and exit. */
- RSPEAK(131);
- score(0);
+ RSPEAK(DEATH_CLOSING);
+ score(endgame);
} else {
- if (!YES(cmdin,79+game.numdie*2,80+game.numdie*2,54))
- score(0);
+ /* FIXME: Arithmetic on message numbers */
+ if (!YES(cmdin,WATCH_IT+game.numdie*2,WHICH_WAY+game.numdie*2,OK_MAN))
+ score(endgame);
if (game.numdie == MAXDIE)
- score(0);
- game.place[WATER]=0;
- game.place[OIL]=0;
+ score(endgame);
+ game.place[WATER] = NOWHERE;
+ game.place[OIL] = NOWHERE;
if (TOTING(LAMP))
game.prop[LAMP]=0;
for (int j=1; j<=NOBJECTS; j++) {
int i=NOBJECTS + 1 - j;
if (TOTING(i)) {
/* Always leave lamp where it's accessible aboveground */
- DROP(i, (i == LAMP) ? 1 : game.oldlc2);
+ DROP(i, (i == LAMP) ? LOC_START : game.oldlc2);
}
}
- game.loc=3;
+ game.loc = LOC_BUILDING;
game.oldloc=game.loc;
}
}
/* Given the current location in "game.loc", and a motion verb number in
- * "K", put the new location in "game.newloc". The current loc is saved
+ * "motion", put the new location in "game.newloc". The current loc is saved
* in "game.oldloc" in case he wants to retreat. The current
* game.oldloc is saved in game.oldlc2, in case he dies. (if he
* does, game.newloc will be limbo, and game.oldloc will be what killed
game.oldlc2=game.oldloc;
game.oldloc=game.loc;
k2=0;
- if (motion == game.loc)k2=91;
- if (CNDBIT(game.loc,NOBACK))k2=274;
+ if (motion == game.loc)k2=FORGOT_PATH;
+ if (CNDBIT(game.loc,NOBACK))k2=TWIST_TURN;
if (k2 == 0) {
for (;;) {
scratchloc=MOD((labs(TRAVEL[kk])/1000),1000);
}
kk=k2;
if (kk == 0) {
- RSPEAK(140);
+ RSPEAK(NOT_CONNECTED);
return true;
}
}
}
else if (motion == LOOK) {
/* Look. Can't give more detail. Pretend it wasn't dark
- * (though it may "now" be dark) so he won't fall into a
+ * (though it may now be dark) so he won't fall into a
* pit while staring into the gloom. */
- if (game.detail < 3)RSPEAK(15);
+ if (game.detail < 3)
+ RSPEAK(NO_MORE_DETAIL);
++game.detail;
game.wzdark=false;
game.abbrev[game.loc]=0;
}
else if (motion == CAVE) {
/* Cave. Different messages depending on whether above ground. */
- RSPEAK((OUTSID(game.loc) && game.loc != 8) ? 57 : 58);
+ RSPEAK((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL);
return true;
}
else {
if (MOD(scratchloc,1000) == 1 || MOD(scratchloc,1000) == motion)
break;
if (TRAVEL[kk] < 0) {
+ /* FIXME: Magic numbers! */
/* Non-applicable motion. Various messages depending on
* word given. */
- int spk=12;
- if (motion >= 43 && motion <= 50)spk=52;
- if (motion == 29 || motion == 30)spk=52;
- if (motion == 7 || motion == 36 || motion == 37)spk=10;
- if (motion == 11 || motion == 19)spk=11;
- if (verb == FIND || verb == INVENT)spk=59;
- if (motion == 62 || motion == 65)spk=42;
- if (motion == 17)spk=80;
+ int spk=CANT_APPLY;
+ if (motion >= 43 && motion <= 50)spk=BAD_DIRECTION;
+ if (motion == 29 || motion == 30)spk=BAD_DIRECTION;
+ if (motion == 7 || motion == 36 || motion == 37)spk=UNSURE_FACING;
+ if (motion == 11 || motion == 19)spk=NO_INOUT_HERE;
+ if (verb == FIND || verb == INVENT)spk=NEreplace;
+ if (motion == 62 || motion == 65)spk=NOTHING_HAPPENS;
+ if (motion == 17)spk=WHICH_WAY;
RSPEAK(spk);
return true;
}
* 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". */
+ /* FIXME: Arithmetic on location numbers */
game.newloc=99+100-game.loc;
if (game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD)))
return true;
game.newloc=game.loc;
- RSPEAK(117);
+ RSPEAK(MUST_DROP);
return true;
case 2:
/* Travel 302. Plover transport. Drop the emerald (only use
game.newloc=PLAC[TROLL]+FIXD[TROLL]-game.loc;
if (game.prop[TROLL] == 0)game.prop[TROLL]=1;
if (!TOTING(BEAR)) return true;
- RSPEAK(162);
+ RSPEAK(BRIDGE_COLLAPSE);
game.prop[CHASM]=1;
game.prop[TROLL]=2;
DROP(BEAR,game.newloc);
BUG(20);
}
} while
- (false);
+ (false);
+ /* FIXME: Arithmetic on location number, becoming a message number */
RSPEAK(game.newloc-500);
game.newloc=game.loc;
return true;
MOVE(TROLL2,PLAC[TROLL]);
MOVE(TROLL2+NOBJECTS,FIXD[TROLL]);
JUGGLE(CHASM);
- if (game.prop[BEAR] != 3)DSTROY(BEAR);
+ if (game.prop[BEAR] != 3)DESTROY(BEAR);
game.prop[CHAIN]=0;
game.fixed[CHAIN]=0;
game.prop[AXE]=0;
game.fixed[AXE]=0;
- RSPEAK(129);
+ RSPEAK(CAVE_CLOSING);
game.clock1= -1;
game.closng=true;
return true;
* objects he might be carrying (lest he have some which
* could cause trouble, such as the keys). We describe the
* flash of light and trundle back. */
- game.prop[BOTTLE]=PUT(BOTTLE,115,1);
- game.prop[PLANT]=PUT(PLANT,115,0);
- game.prop[OYSTER]=PUT(OYSTER,115,0);
+ game.prop[BOTTLE]=PUT(BOTTLE,LOC_NE,1);
+ game.prop[PLANT]=PUT(PLANT,LOC_NE,0);
+ game.prop[OYSTER]=PUT(OYSTER,LOC_NE,0);
OBJTXT[OYSTER]=3;
- game.prop[LAMP]=PUT(LAMP,115,0);
- game.prop[ROD]=PUT(ROD,115,0);
- game.prop[DWARF]=PUT(DWARF,115,0);
- game.loc=115;
- game.oldloc=115;
- game.newloc=115;
+ game.prop[LAMP]=PUT(LAMP,LOC_NE,0);
+ game.prop[ROD]=PUT(ROD,LOC_NE,0);
+ game.prop[DWARF]=PUT(DWARF,LOC_NE,0);
+ game.loc = LOC_NE;
+ game.oldloc = LOC_NE;
+ game.newloc = LOC_NE;
/* Leave the grate with normal (non-negative) property.
* Reuse sign. */
- PUT(GRATE,116,0);
- PUT(SIGN,116,0);
+ PUT(GRATE,LOC_SW,0);
+ PUT(SIGN,LOC_SW,0);
++OBJTXT[SIGN];
- game.prop[SNAKE]=PUT(SNAKE,116,1);
- game.prop[BIRD]=PUT(BIRD,116,1);
- game.prop[CAGE]=PUT(CAGE,116,0);
- game.prop[ROD2]=PUT(ROD2,116,0);
- game.prop[PILLOW]=PUT(PILLOW,116,0);
+ game.prop[SNAKE]=PUT(SNAKE,LOC_SW,1);
+ game.prop[BIRD]=PUT(BIRD,LOC_SW,1);
+ game.prop[CAGE]=PUT(CAGE,LOC_SW,0);
+ game.prop[ROD2]=PUT(ROD2,LOC_SW,0);
+ game.prop[PILLOW]=PUT(PILLOW,LOC_SW,0);
- game.prop[MIRROR]=PUT(MIRROR,115,0);
- game.fixed[MIRROR]=116;
+ game.prop[MIRROR]=PUT(MIRROR,LOC_NE,0);
+ game.fixed[MIRROR]=LOC_SW;
for (int i=1; i<=NOBJECTS; i++) {
if (TOTING(i))
- DSTROY(i);
+ DESTROY(i);
}
- RSPEAK(132);
+ RSPEAK(CAVE_CLOSED);
game.closed=true;
return true;
}
* Second is for other cases of lamp dying. 12400 is when it
* goes out. Even then, he can explore outside for a while
* if desired. */
- if (game.limit<=30 && HERE(BATTER) && game.prop[BATTER]==0 && HERE(LAMP))
+ if (game.limit <= WARNTIME && HERE(BATTER) && game.prop[BATTER]==0 && HERE(LAMP))
{
- RSPEAK(188);
+ RSPEAK(REPLACE_BATTERIES);
game.prop[BATTER]=1;
if (TOTING(BATTER))
DROP(BATTER,game.loc);
game.limit= -1;
game.prop[LAMP]=0;
if (HERE(LAMP))
- RSPEAK(184);
- } else if (game.limit <= 30) {
+ RSPEAK(LAMP_OUT);
+ } else if (game.limit <= WARNTIME) {
if (!game.lmwarn && HERE(LAMP)) {
game.lmwarn=true;
- int spk=187;
- if (game.place[BATTER] == 0)spk=183;
- if (game.prop[BATTER] == 1)spk=189;
+ int spk=GET_BATTERIES;
+ if (game.place[BATTER] == NOWHERE)spk=LAMP_DIM;
+ if (game.prop[BATTER] == 1)spk=MISSING_BATTERIES;
RSPEAK(spk);
}
}
* get full score. */
{
if (!DARK(game.loc)) {
- long obj;
++game.abbrev[game.loc];
for (int i=game.atloc[game.loc]; i != 0; i=game.link[i]) {
- obj=i;
+ long obj=i;
if (obj > NOBJECTS)obj=obj-NOBJECTS;
if (obj == STEPS && TOTING(NUGGET))
continue;
static bool do_command(FILE *cmdin)
/* Get and execute a command */
{
- long KQ, verb, V1, V2;
- long i, k, KMOD;
+ long kq, verb, V1, V2;
+ long i, k, kmod;
static long igo = 0;
static long obj = 0;
enum speechpart part;
/* Can't leave cave once it's closing (except by main office). */
if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) {
- RSPEAK(130);
+ RSPEAK(EXIT_CLOSED);
game.newloc=game.loc;
if (!game.panic)game.clock2=15;
game.panic=true;
for (i=1; i<=NDWARVES-1; i++) {
if (game.odloc[i] == game.newloc && game.dseen[i]) {
game.newloc=game.loc;
- RSPEAK(2);
+ RSPEAK(DWARF_BLOCK);
break;
}
}
for (;;) {
if (game.loc == 0)
croak(cmdin);
- char* msg = short_location_descriptions[game.loc];
+ char* msg = locations[game.loc].description.small;
if (MOD(game.abbrev[game.loc],game.abbnum) == 0 || msg == 0)
- msg=long_location_descriptions[game.loc];
+ msg=locations[game.loc].description.big;
if (!FORCED(game.loc) && DARK(game.loc)) {
/* The easiest way to get killed is to fall into a pit in
* pitch darkness. */
if (game.wzdark && PCT(35)) {
- RSPEAK(23);
+ RSPEAK(PIT_FALL);
game.oldlc2 = game.loc;
croak(cmdin);
continue; /* back to top of main interpreter loop */
}
- msg=arbitrary_messages[16];
+ msg=arbitrary_messages[PITCH_DARK];
}
- if (TOTING(BEAR))RSPEAK(141);
+ if (TOTING(BEAR))RSPEAK(TAME_BEAR);
newspeak(msg);
if (FORCED(game.loc)) {
if (playermove(cmdin, verb, 1))
else
continue; /* back to top of main interpreter loop */
}
- if (game.loc == 33 && PCT(25) && !game.closng)RSPEAK(7);
+ if (game.loc == 33 && PCT(25) && !game.closng)RSPEAK(SAYS_PLUGH);
listobjects();
} else
lampcheck();
- k=43;
- if (LIQLOC(game.loc) == WATER)k=70;
+ k=WHERE_QUERY;
+ if (LIQLOC(game.loc) == WATER)k=FEET_WET;
V1=VOCAB(WD1,-1);
V2=VOCAB(WD2,-1);
if (V1 == ENTER && (V2 == STREAM || V2 == 1000+WATER)) {
if (WD1 == MAKEWD(23051920)) {
++game.iwest;
if (game.iwest == 10)
- RSPEAK(17);
+ RSPEAK(W_IS_WEST);
}
if (WD1 == MAKEWD( 715) && WD2 != 0) {
if (++igo == 10)
- RSPEAK(276);
+ RSPEAK(GO_UNNEEDED);
}
L2630:
i=VOCAB(WD1,-1);
if (i == -1) {
/* Gee, I don't understand. */
if (fallback_handler(rawbuf))
- return true;
+ continue;
SETPRM(1,WD1,WD1X);
- RSPEAK(254);
+ RSPEAK(DONT_KNOW);
goto L2600;
}
- KMOD=MOD(i,1000);
- KQ=i/1000+1;
- switch (KQ-1)
+ kmod=MOD(i,1000);
+ kq=i/1000+1;
+ switch (kq-1)
{
case 0:
- if (playermove(cmdin, verb, KMOD))
+ if (playermove(cmdin, verb, kmod))
return true;
else
continue; /* back to top of main interpreter loop */
- case 1: part=unknown; obj = KMOD; break;
- case 2: part=intransitive; verb = KMOD; break;
- case 3: RSPEAK(KMOD); goto L2012;
+ case 1: part=unknown; obj = kmod; break;
+ case 2: part=intransitive; verb = kmod; break;
+ case 3: RSPEAK(kmod); goto L2012;
default: BUG(22);
}
/* Random intransitive verbs come here. Clear obj just in case
* (see attack()). */
SETPRM(1,WD1,WD1X);
- RSPEAK(257);
+ RSPEAK(DO_WHAT);
obj=0;
goto L2600;
case GO_DWARFWAKE:
/* Oh dear, he's disturbed the dwarves. */
- RSPEAK(136);
- score(0);
+ RSPEAK(DWARVES_AWAKEN);
+ score(endgame);
return true;
default:
BUG(99);