X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=newdungeon.py;h=60625997f907ddc4976fd39b1ce406f5d546637f;hp=a4b230e80faac1cacc98725b3e2df1223e002dcf;hb=3b780dd57e295b57ba78649e008fede10e07cdd9;hpb=20a645bdf42e494262e897210100d8a1f8f9dd18 diff --git a/newdungeon.py b/newdungeon.py index a4b230e..6062599 100755 --- a/newdungeon.py +++ b/newdungeon.py @@ -8,7 +8,7 @@ # movement rules to the travel array that's actually used by # playermove(). This program first compiles the YAML to a form # identical to the data in section 3 of the old adventure.text file, -# then a second stage packs that data into the travel array. +# then a second stage unpacks that data into the travel array. # # Here are the rules of the intermediate form: # @@ -137,6 +137,23 @@ typedef struct {{ const long message; }} action_t; +typedef struct {{ + const long motion; + const long dest; + const bool stop; +}} travelop_t; + +/* Abstract out the encoding of words in the travel array. Gives us + * some hope of getting to a less cryptic representation than we + * inherited from FORTRAN, someday. To understand these, read the + * encoding description for travel. + */ +#define T_DESTINATION(entry) MOD((entry).dest, 1000) +#define T_NODWARVES(entry) ((entry).dest / 1000 == 100) +#define T_HIGH(entry) ((entry).dest) +#define T_TERMINATE(entry) ((entry).motion == 1) +#define L_SPEAK(loc) ((loc) - 500) + extern const location_t locations[]; extern const object_t objects[]; extern const char* arbitrary_messages[]; @@ -147,6 +164,8 @@ extern const hint_t hints[]; extern long conditions[]; extern const motion_t motions[]; extern const action_t actions[]; +extern const travelop_t travel[]; +extern const long tkey[]; #define NLOCATIONS {} #define NOBJECTS {} @@ -156,6 +175,7 @@ extern const action_t actions[]; #define NTHRESHOLDS {} #define NACTIONS {} #define NTRAVEL {} +#define NKEYS {} enum arbitrary_messages_refs {{ {} @@ -228,6 +248,12 @@ const action_t actions[] = {{ {} }}; +{} + +const travelop_t travel[] = {{ +{} +}}; + /* end */ """ @@ -446,6 +472,58 @@ def recompose(type_word, value): sys.stderr.write("%s is not a known word classifier\n" % attrs["type"]) sys.exit(1) +def get_motions(motions): + template = """ {{ + .words = {}, + }}, +""" + mot_str = "" + for motion in motions: + contents = motion[1] + if contents["words"] == None: + mot_str += template.format("NULL") + continue + c_words = [make_c_string(s) for s in contents["words"]] + words_str = "(const char* []) {" + ", ".join(c_words) + "}" + mot_str += template.format(words_str) + return mot_str + +def get_actions(actions): + template = """ {{ + .words = {}, + .message = {}, + }}, +""" + act_str = "" + for action in actions: + contents = action[1] + + if contents["words"] == None: + words_str = "NULL" + else: + c_words = [make_c_string(s) for s in contents["words"]] + words_str = "(const char* []) {" + ", ".join(c_words) + "}" + + if contents["message"] == None: + message = "NO_MESSAGE" + else: + message = contents["message"] + + act_str += template.format(words_str, message) + act_str = act_str[:-1] # trim trailing newline + return act_str + +def bigdump(arr): + out = "" + for (i, entry) in enumerate(arr): + if i % 10 == 0: + if out and out[-1] == ' ': + out = out[:-1] + out += "\n " + out += str(arr[i]) + ", " + out = out[:-2] + "\n" + return out + def buildtravel(locs, objs, voc): ltravel = [] verbmap = {} @@ -489,14 +567,26 @@ def buildtravel(locs, objs, voc): elif cond[0] == "not": # FIXME: Allow named as well as numbered states try: - return 300 + objnames.index(cond[1]) + 100 * cond[2] + obj = objnames.index(cond[1]) + if type(cond[2]) == int: + state = cond[2] + else: + for (i, stateclause) in enumerate(objs[obj][1]["longs"]): + if type(stateclause) == list: + if stateclause[0] == cond[2]: + state = i + break + else: + sys.stderr.write("dungeon: unmatched state symbol %s in not clause of %s\n" % (cond[2], name)) + sys.exit(0); + return 300 + obj + 100 * state except ValueError: sys.stderr.write("dungeon: unknown object name %s in not clause of %s\n" % (cond[1], name)) sys.exit(1) else: print(cond) raise ValueError - # Much more to be done here + for (i, (name, loc)) in enumerate(locs): if "travel" in loc: for rule in loc["travel"]: @@ -507,58 +597,6 @@ def buildtravel(locs, objs, voc): if not rule["verbs"]: tt.append(1) ltravel.append(tuple(tt)) - return tuple(ltravel) - -def get_motions(motions): - template = """ {{ - .words = {}, - }}, -""" - mot_str = "" - for motion in motions: - contents = motion[1] - if contents["words"] == None: - mot_str += template.format("NULL") - continue - c_words = [make_c_string(s) for s in contents["words"]] - words_str = "(const char* []) {" + ", ".join(c_words) + "}" - mot_str += template.format(words_str) - return mot_str - -def get_actions(actions): - template = """ {{ - .words = {}, - .message = {}, - }}, -""" - act_str = "" - for action in actions: - contents = action[1] - - if contents["words"] == None: - words_str = "NULL" - else: - c_words = [make_c_string(s) for s in contents["words"]] - words_str = "(const char* []) {" + ", ".join(c_words) + "}" - - if contents["message"] == None: - message = "NO_MESSAGE" - else: - message = contents["message"] - - act_str += template.format(words_str, message) - act_str = act_str[:-1] # trim trailing newline - return act_str - -if __name__ == "__main__": - with open(yaml_name, "r") as f: - db = yaml.load(f) - - locnames = [x[0] for x in db["locations"]] - msgnames = [el[0] for el in db["arbitrary_messages"]] - objnames = [el[0] for el in db["objects"]] - - travel = buildtravel(db["locations"], db["objects"], db["vocabulary"]) # At this point the ltravel data is in the Section 3 # representation from the FORTRAN version. Next we perform the @@ -581,6 +619,50 @@ if __name__ == "__main__": # } # TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1]; # } + # + # In order to de-crypticize the runtime code, we're going to break these + # magic numbers up into a struct. + travel = [[0, 0, False]] + tkey = [0] + oldloc = 0 + while ltravel: + rule = list(ltravel.pop(0)) + loc = rule.pop(0) + newloc = rule.pop(0) + if loc != oldloc: + tkey.append(len(travel)) + oldloc = loc + elif travel: + travel[-1][2] = not travel[-1][2] + while rule: + travel.append([rule.pop(0), newloc, False]) + travel[-1][2] = True + return (travel, tkey) + +def get_travel(travel): + template = """ {{ + .motion = {}, + .dest = {}, + .stop = {}, + }}, +""" + out = "" + for entry in travel: + out += template.format(entry[0], entry[1], entry[2]).lower() + out = out[:-1] # trim trailing newline + return out + +if __name__ == "__main__": + with open(yaml_name, "r") as f: + db = yaml.load(f) + + locnames = [x[0] for x in db["locations"]] + msgnames = [el[0] for el in db["arbitrary_messages"]] + objnames = [el[0] for el in db["objects"]] + + (travel, tkey) = buildtravel(db["locations"], + db["objects"], + db["vocabulary"]) c = c_template.format( h_name, @@ -594,6 +676,8 @@ if __name__ == "__main__": get_condbits(db["locations"]), get_motions(db["motions"]), get_actions(db["actions"]), + "const long tkey[] = {%s};" % bigdump(tkey), + get_travel(travel), ) h = h_template.format( @@ -605,6 +689,7 @@ if __name__ == "__main__": len(db["turn_thresholds"]), len(db["actions"]), len(travel), + len(tkey), get_refs(db["arbitrary_messages"]), get_refs(db["locations"]), get_refs(db["objects"]),