From: NHOrus Date: Sun, 10 Sep 2017 21:13:55 +0000 (+0300) Subject: Put some of important parameters into fixed width signed integers X-Git-Tag: 1.5~19 X-Git-Url: https://jxself.org/git/?a=commitdiff_plain;h=9e2cb3c19196a26af8e20803314f42b69dc0e014;p=open-adventure.git Put some of important parameters into fixed width signed integers Massaged test files. Fixes issue #41 --- diff --git a/actions.c b/actions.c index 3808f9b..e41c7bf 100644 --- a/actions.c +++ b/actions.c @@ -1250,7 +1250,7 @@ static int wake(verb_t verb, obj_t obj) static int seed(verb_t verb, const char *arg) /* Set seed */ { - int seed = atoi(arg); + int32_t seed = strtol(arg, NULL, 10); speak(actions[verb].message, seed); set_seed(seed); --game.turns; diff --git a/advent.h b/advent.h index 17ae719..788d659 100644 --- a/advent.h +++ b/advent.h @@ -2,9 +2,16 @@ #include #include #include +#include #include "dungeon.h" +/* LCG PRNG parameters tested against + * Knuth vol. 2. by the original authors */ +#define LCG_A 1093 +#define LCG_C 221587 +#define LCG_M 1048576 + #define LINESIZE 1024 #define TOKLEN 5 // № sigificant characters in a token */ #define NDWARVES 6 // number of dwarves @@ -112,7 +119,7 @@ typedef long loc_t; // index into the locations array */ typedef long turn_t; // turn counter or threshold */ struct game_t { - unsigned long lcg_a, lcg_c, lcg_m, lcg_x; + int64_t lcg_x; long abbnum; // How often to print long descriptions score_t bonus; // What kind of finishing bonus we are getting loc_t chloc; // pirate chest location @@ -122,6 +129,11 @@ struct game_t { bool clshnt; // has player read the clue in the endgame? bool closed; // whether we're all the way closed bool closng; // whether it's closing time yet + bool lmwarn; // has player been warned about lamp going dim? + bool novice; // asked for instructions at start-up? + bool panic; // has player found out he's trapped? + bool wzdark; // whether the loc he's leaving was dark + bool blooded; // has player drunk of dragon's blood? long conds; // min value for cond[loc] if loc has any hints long detail; // level of detail in descriptions @@ -141,24 +153,19 @@ struct game_t { long iwest; // # times he's said "west" instead of "w" long knfloc; // knife location; 0 if none, -1 after caveat turn_t limit; // lifetime of lamp - bool lmwarn; // has player been warned about lamp going dim? loc_t loc; // where player is now loc_t newloc; // where player is going - bool novice; // asked for instructions at start-up? turn_t numdie; // number of times killed so far loc_t oldloc; // where player was loc_t oldlc2; // where player was two moves ago obj_t oldobj; // last object player handled - bool panic; // has player found out he's trapped? long saved; // point penalty for saves long tally; // count of treasures gained long thresh; // current threshold for endgame scoring tier turn_t trndex; // FIXME: not used, remove on next format bump turn_t trnluz; // # points lost so far due to turns used turn_t turns; // counts commands given (ignores yes/no) - bool wzdark; // whether the loc he's leaving was dark char zzword[TOKLEN + 1]; // randomly generated magic word from bird - bool blooded; // has player drunk of dragon's blood? long abbrev[NLOCATIONS + 1]; // has location been seen? long atloc[NLOCATIONS + 1]; // head of object linked list per location long dseen[NDWARVES + 1]; // true if dwarf has seen him @@ -214,11 +221,11 @@ extern void drop(obj_t, loc_t); extern int atdwrf(loc_t); extern long setbit(int); extern bool tstbit(long, int); -extern void set_seed(long); -extern long randrange(long); +extern void set_seed(int32_t); +extern int32_t randrange(int32_t); extern long score(enum termination); extern void terminate(enum termination) __attribute__((noreturn)); -extern int savefile(FILE *, long); +extern int savefile(FILE *, int32_t); extern int suspend(void); extern int resume(void); extern int restore(FILE *); diff --git a/init.c b/init.c index be5c3fb..fbe4410 100644 --- a/init.c +++ b/init.c @@ -37,12 +37,6 @@ struct game_t game = { .loc = LOC_START, .limit = GAMELIMIT, .foobar = WORD_EMPTY, - - /* Initialize our LCG PRNG with parameters tested against - * Knuth vol. 2. by the original authors */ - .lcg_a = 1093, - .lcg_c = 221587, - .lcg_m = 1048576, }; long initialise(void) diff --git a/misc.c b/misc.c index 03681d0..302e61c 100644 --- a/misc.c +++ b/misc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "advent.h" #include "dungeon.h" @@ -66,8 +67,8 @@ static void vspeak(const char* msg, bool blank, va_list ap) i++; // Integer specifier. if (msg[i] == 'd') { - long arg = va_arg(ap, long); - int ret = snprintf(renderp, size, "%ld", arg); + int32_t arg = va_arg(ap, int32_t); + int ret = snprintf(renderp, size, "%" PRId32, arg); if (ret < size) { renderp += ret; size -= ret; @@ -642,10 +643,10 @@ bool tstbit(long mask, int bit) return (mask & (1 << bit)) != 0; } -void set_seed(long seedval) +void set_seed(int32_t seedval) /* Set the LCG seed */ { - game.lcg_x = (unsigned long) seedval % game.lcg_m; + game.lcg_x = (uint32_t) seedval % LCG_M; // once seed is set, we need to generate the Z`ZZZ word for (int i = 0; i < 5; ++i) { @@ -655,18 +656,18 @@ void set_seed(long seedval) game.zzword[5] = '\0'; } -static unsigned long get_next_lcg_value(void) +static int32_t get_next_lcg_value(void) /* Return the LCG's current value, and then iterate it. */ { - unsigned long old_x = game.lcg_x; - game.lcg_x = (game.lcg_a * game.lcg_x + game.lcg_c) % game.lcg_m; + int32_t old_x = game.lcg_x; + game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M; return old_x; } -long randrange(long range) +int32_t randrange(int32_t range) /* Return a random integer from [0, range). */ { - return range * get_next_lcg_value() / game.lcg_m; + return range * get_next_lcg_value() / LCG_M; } // LCOV_EXCL_START diff --git a/saveresume.c b/saveresume.c index cc000d8..f1d52d4 100644 --- a/saveresume.c +++ b/saveresume.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "advent.h" #include "dungeon.h" @@ -11,7 +12,7 @@ * see the history.adoc file in the source distribution for discussion. */ -#define VRSION 27 /* bump on save format change */ +#define VRSION 28 /* bump on save format change */ /* * If you change the first three members, the resume function may not properly @@ -20,16 +21,16 @@ * when you do that. */ struct save_t { - long savetime; - long mode; /* not used, must be present for version detection */ - long version; + int64_t savetime; + int32_t mode; /* not used, must be present for version detection */ + int32_t version; struct game_t game; }; struct save_t save; #define IGNORE(r) do{if (r){}}while(0) -int savefile(FILE *fp, long version) +int savefile(FILE *fp, int32_t version) /* Save game to file. No input or output from user. */ { save.savetime = time(NULL); @@ -139,15 +140,9 @@ bool is_valid(struct game_t* valgame) return false; } - /* Prevent RNG substitution. Why we are saving PRNG parameters? */ - - if (valgame->lcg_a != game.lcg_a || valgame->lcg_c != game.lcg_c || valgame->lcg_m != game.lcg_m) { - return false; - } - /* Check for RNG overflow. Truncate */ - if (valgame->lcg_x >= game.lcg_m) { - valgame->lcg_x %= game.lcg_m; + if (valgame->lcg_x >= LCG_M) { + valgame->lcg_x %= LCG_M; } /* Bounds check for locations */ @@ -241,4 +236,4 @@ bool is_valid(struct game_t* valgame) return true; } -/* end */ \ No newline at end of file +/* end */ diff --git a/tests/illformed.chk b/tests/illformed.chk index 20f18c9..3c763af 100644 --- a/tests/illformed.chk +++ b/tests/illformed.chk @@ -669,7 +669,7 @@ The grate is locked. > seed -123 -Seed set to 4294967173 +Seed set to -123 You're outside grate. diff --git a/tests/resumefail2.chk b/tests/resumefail2.chk index cdda771..a34e001 100644 --- a/tests/resumefail2.chk +++ b/tests/resumefail2.chk @@ -11,7 +11,7 @@ down a gully. Can't open file y, try again. I'm sorry, but that Adventure was begun using Version -133.-7 of the -save file format, and this program uses Version 2.7. You must find an instance +save file format, and this program uses Version 2.8. You must find an instance using that other version in order to resume that Adventure. You're in front of building.