Eliminate magic numbers from C side of condition handling.

This commit is contained in:
Eric S. Raymond 2017-07-07 09:36:43 -04:00
parent 2bdf9e2803
commit 1cbc3d827b
4 changed files with 51 additions and 18 deletions

View file

@ -12,7 +12,6 @@
#define DALTLC LOC_NUGGET // alternate dwarf location
#define INVLIMIT 7 // inverntory limit (# of objects)
#define INTRANSITIVE -1 // illegal object number
#define SPECIALBASE 300 // base number of special rooms
#define GAMELIMIT 330 // base limit of turns
#define NOVICELIMIT 1000 // limit of turns for novice
#define WARNTIME 30 // late game starts at game.limit-this
@ -65,7 +64,6 @@
#define PCT(N) (randrange(100) < (N))
#define GSTONE(OBJ) ((OBJ) == EMERALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH)
#define FOREST(LOC) CNDBIT(LOC, COND_FOREST)
#define SPECIAL(LOC) ((LOC) > SPECIALBASE)
#define OUTSID(LOC) (CNDBIT(LOC, COND_ABOVE) || FOREST(LOC))
#define INDEEP(LOC) ((LOC) >= LOC_MISTHALL && !OUTSID(LOC))
#define BUG(x) bug(x, #x)

23
main.c
View file

@ -509,7 +509,9 @@ static void croak(void)
static bool traveleq(long a, long b)
/* Are two travel entries equal for purposes of skip after failed condition? */
{
return (travel[a].cond == travel[b].cond)
return (travel[a].condtype == travel[b].condtype)
&& (travel[a].condarg1 == travel[b].condarg1)
&& (travel[a].condarg2 == travel[b].condarg2)
&& (travel[a].desttype == travel[b].desttype)
&& (travel[a].destval == travel[b].destval);
}
@ -634,22 +636,23 @@ static void playermove( int motion)
do {
for (;;) { /* L12 loop */
for (;;) {
long cond = travel[travel_entry].cond;
long arg = MOD(cond, 100);
if (!SPECIAL(cond)) {
enum condtype_t condtype = travel[travel_entry].condtype;
long condarg1 = travel[travel_entry].condarg1;
long condarg2 = travel[travel_entry].condarg2;
if (condtype < cond_not) {
/* YAML N and [pct N] conditionals */
if (cond <= 100) {
if (cond == 0 ||
PCT(cond))
if (condtype == cond_goto || condtype == cond_pct) {
if (condarg1 == 0 ||
PCT(condarg1))
break;
/* else fall through */
}
/* YAML [with OBJ] clause */
if (TOTING(arg) ||
(cond > 200 && AT(arg)))
if (TOTING(condarg1) ||
(condtype == cond_with && AT(condarg1)))
break;
/* else fall through to check [not OBJ STATE] */
} else if (game.prop[arg] != cond / 100 - 3)
} else if (game.prop[condarg1] != condarg2)
break;
/* We arrive here on conditional failure.

View file

@ -149,11 +149,14 @@ typedef struct {{
const char* message;
}} special_t;
enum condtype_t {{cond_goto, cond_pct, cond_carry, cond_with, cond_not}};
enum desttype_t {{dest_goto, dest_special, dest_speak}};
typedef struct {{
const long motion;
const long cond;
const long condtype;
const long condarg1;
const long condarg2;
const enum desttype_t desttype;
const long destval;
const bool nodwarves;
@ -704,7 +707,7 @@ def buildtravel(locs, objs):
#
# In order to de-crypticize the runtime code, we're going to break these
# magic numbers up into a struct.
travel = [[0, "LOC_NOWHERE", 0, 0, 0, 0, "false", "false"]]
travel = [[0, "LOC_NOWHERE", 0, 0, 0, 0, 0, 0, "false", "false"]]
tkey = [0]
oldloc = 0
while ltravel:
@ -718,6 +721,30 @@ def buildtravel(locs, objs):
travel[-1][-1] = "false" if travel[-1][-1] == "true" else "true"
while rule:
cond = newloc // 1000
nodwarves = (cond == 100)
if cond == 0:
condtype = "cond_goto"
condarg1 = condarg2 = 0
elif cond < 100:
condtype = "cond_pct"
condarg1 = cond
condarg2 = 0
elif cond == 100:
condtype = "cond_goto"
condarg1 = 100
condarg2 = 0
elif cond <= 200:
condtype = "cond_carry"
condarg1 = objnames[cond - 100]
condarg2 = 0
elif cond <= 300:
condtype = "cond_with"
condarg1 = objnames[cond - 200]
condarg2 = 0
else:
condtype = "cond_not"
condarg1 = cond % 100
condarg2 = (cond - 300) // 100.
dest = newloc % 1000
if dest <= 300:
desttype = "dest_goto";
@ -731,10 +758,12 @@ def buildtravel(locs, objs):
travel.append([len(tkey)-1,
locnames[len(tkey)-1],
rule.pop(0),
cond,
condtype,
condarg1,
condarg2,
desttype,
destval,
"true" if cond==100 else "false",
"true" if nodwarves else "false",
"false"])
travel[-1][-1] = "true"
return (travel, tkey)
@ -742,7 +771,9 @@ def buildtravel(locs, objs):
def get_travel(travel):
template = """ {{ // from {}: {}
.motion = {},
.cond = {},
.condtype = {},
.condarg1 = {},
.condarg2 = {},
.desttype = {},
.destval = {},
.nodwarves = {},

3
misc.c
View file

@ -571,7 +571,8 @@ void move(obj_t object, loc_t where)
from = game.fixed[object - NOBJECTS];
else
from = game.place[object];
if (from != LOC_NOWHERE && from != CARRIED && !SPECIAL(from))
/* (ESR) Used to check for !SPECIAL(from). I *think* that was wrong... */
if (from != LOC_NOWHERE && from != CARRIED)
carry(object, from);
drop(object, where);
}