From 111279ad59a25bc548c47d38c1a52c3036eff87a Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Tue, 6 Aug 2013 04:19:06 +0200 Subject: [PATCH] Moved pseudo-random generator into its own library, simplified its interface and internals. --- src/main.c | 15 ++++++++------- src/map.c | 7 ++++--- src/map_object_actions.c | 5 +++-- src/misc.c | 22 ++++------------------ src/misc.h | 11 ----------- src/rrand.c | 23 +++++++++++++++++++++++ src/rrand.h | 27 +++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 src/rrand.c create mode 100644 src/rrand.h diff --git a/src/main.c b/src/main.c index 2b16733..9c2b87e 100644 --- a/src/main.c +++ b/src/main.c @@ -23,10 +23,11 @@ */ #include "map_object_actions.h" /* for player_wait(), move_player() */ #include "map.h" /* for struct Map, init_map() */ -#include "misc.h" /* for rrand(), update_log(), toggle_window(), exit_game(), +#include "misc.h" /* for update_log(), toggle_window(), exit_game(), * find_passable_pos(), meta_keys(), save_game() */ #include "yx_uint16.h" /* for dir enum */ +#include "rrand.h" /* for rrand(), rrand_seed() */ int main(int argc, char *argv[]) { @@ -102,26 +103,26 @@ int main(int argc, char *argv[]) /* Generate map from seed and, if newly generated world, start positions of * actors. */ - rrand(1, world.seed); + rrand_seed(world.seed); struct Map map = init_map(); world.map = ↦ if (1 == world.turn) { player.pos = find_passable_pos(&map); void * foo = build_map_objects(&world, &world.monster, - 0, 1 + rrand(0,0) % 27, + 0, 1 + rrand() % 27, sizeof(struct Monster), build_map_objects_monsterdata); - foo = build_map_objects(&world, foo, 1, 1 + rrand(0,0) % 9, + foo = build_map_objects(&world, foo, 1, 1 + rrand() % 9, sizeof(struct Monster), build_map_objects_monsterdata); - build_map_objects(&world, foo, 2, 1 + rrand(0,0) % 3, + build_map_objects(&world, foo, 2, 1 + rrand() % 3, sizeof(struct Monster), build_map_objects_monsterdata); - foo = build_map_objects(&world, &world.item, 3, 1 + rrand(0,0) % 3, + foo = build_map_objects(&world, &world.item, 3, 1 + rrand() % 3, sizeof(struct Item), build_map_objects_itemdata); - build_map_objects(&world, foo, 4, 1 + rrand(0,0) % 3, + build_map_objects(&world, foo, 4, 1 + rrand() % 3, sizeof(struct Item), build_map_objects_itemdata); } diff --git a/src/map.c b/src/map.c index 44a0057..a975043 100644 --- a/src/map.c +++ b/src/map.c @@ -1,9 +1,10 @@ #include "map.h" #include /* for malloc() */ #include /* for uint16_t, uint32_t */ -#include "misc.h" /* for rrand() and center_offset() */ +#include "misc.h" /* for center_offset() */ #include "map_objects.h" /* for Player struct */ #include "yx_uint16.h" /* for yx_uint16 and dir enums */ +#include "rrand.h" /* for rrand() */ @@ -28,8 +29,8 @@ struct Map init_map () uint32_t curpos; while (1) { - y = rrand(0, 0) % map.size.y; - x = rrand(0, 0) % map.size.x; + y = rrand() % map.size.y; + x = rrand() % map.size.x; curpos = y * map.size.x + x; if ('~' == map.cells[curpos] && ((curpos >= map.size.x && '.' == map.cells[curpos - map.size.x]) diff --git a/src/map_object_actions.c b/src/map_object_actions.c index 86b7118..58915f6 100644 --- a/src/map_object_actions.c +++ b/src/map_object_actions.c @@ -3,16 +3,17 @@ #include "map_object_actions.h" #include /* for malloc(), calloc(), free() */ #include "yx_uint16.h" /* for yx_uint16 struct, mv_yx_in_dir(), yx_uint16_cmp */ -#include "misc.h" /* for rrand(), update_log(), turn_over()*/ +#include "misc.h" /* for update_log(), turn_over()*/ #include "map.h" /* for Map struct */ #include "main.h" /* for World struct */ #include "map_objects.h" /* for map object (definition) structs */ +#include "rrand.h" /* for rrand() */ extern void move_monster(struct World * world, struct Monster * monster) { - char d = rrand(0, 0) % 5; + char d = rrand() % 5; struct yx_uint16 t = mv_yx_in_dir(d, monster->map_obj.pos); char * msg = malloc(100); struct MapObjDef * mod = get_map_obj_def(world, monster->map_obj.type); diff --git a/src/misc.c b/src/misc.c index 6ac01c7..b324058 100644 --- a/src/misc.c +++ b/src/misc.c @@ -20,6 +20,7 @@ #include "map.h" /* for map_scroll(),map_center_player(), Map struct,dir enum */ #include "main.h" /* for World struct */ #include "yx_uint16.h" /* for yx_uint16 */ +#include "rrand.h" /* for rrand(), rrand_seed() */ @@ -74,21 +75,6 @@ extern void textfile_sizes(FILE * file, uint16_t * linemax_p, -extern uint16_t rrand(char use_seed, uint32_t new_seed) -{ - static uint32_t seed; - if (0 != use_seed) - { - seed = new_seed; - } - - /* Constants as recommended by POSIX.1-2001 (see man page rand(3)). */ - seed = ((seed * 1103515245) + 12345) % 2147483648; - - return (seed >> 16); /* Ignore less random least significant 16 bits. */ -} - - extern void update_log(struct World * world, char * text) { static char * last_msg; @@ -153,7 +139,7 @@ extern void turn_over(struct World * world, char action) fclose(file); } world->turn++; - rrand(1, world->seed * world->turn); + rrand_seed(world->seed * world->turn); struct Monster * monster; for (monster = world->monster; monster != 0; @@ -240,8 +226,8 @@ extern struct yx_uint16 find_passable_pos(struct Map * map) struct yx_uint16 pos; for (pos.y = pos.x = 0; 0 == is_passable(map, pos);) { - pos.y = rrand(0, 0) % map->size.y; - pos.x = rrand(0, 0) % map->size.x; + pos.y = rrand() % map->size.y; + pos.x = rrand() % map->size.x; } return pos; } diff --git a/src/misc.h b/src/misc.h index 6257b12..4d26f10 100644 --- a/src/misc.h +++ b/src/misc.h @@ -32,17 +32,6 @@ extern void textfile_sizes(FILE * file, uint16_t * linemax_p, -/* Pseudo-random number generator using a Linear Congruential Generator - * algorithm with some proven constants. Used instead of rand() to ensure - * portable pseudo-randomness predictability. Set "use_seed" to !0 to seed it - * with "new_seed". - * - * TODO: Write a wrapper for all non-seeding uses that demands no input. - */ -extern uint16_t rrand(char use_seed, uint32_t new_seed); - - - /* Update game log by appending "text", or by appending a "." if "text" is the * same as the last one passed. */ diff --git a/src/rrand.c b/src/rrand.c new file mode 100644 index 0000000..f790ac1 --- /dev/null +++ b/src/rrand.c @@ -0,0 +1,23 @@ +#include "rrand.h" +#include /* for uint16_t, uint32_t */ + + + +static uint32_t seed = 0; + + + +extern uint16_t rrand() +{ + /* Constants as recommended by POSIX.1-2001 (see man page rand(3)). */ + seed = ((seed * 1103515245) + 12345) % 2147483648; + + return (seed >> 16); /* Ignore less random least significant 16 bits. */ +} + + + +extern void rrand_seed(uint32_t new_seed) +{ + seed = new_seed; +} diff --git a/src/rrand.h b/src/rrand.h new file mode 100644 index 0000000..1b18057 --- /dev/null +++ b/src/rrand.h @@ -0,0 +1,27 @@ +/* rrand.h + * + * Provide pseudo-random numbers via a Linear Congruential Generator algorithm + * with some proven constants. Use these functions instead of rand() and + * srand() to ensure portable pseudo-randomness portability. + */ + + + +#ifndef RRAND_H +#define RRAND_H + +#include /* for uint32_t */ + + + +/* Return 16-bit number pseudo-randomly generated. */ +extern uint16_t rrand(); + + + +/* Set seed that rrand() starts from. */ +extern void rrand_seed(uint32_t new_seed); + + + +#endif -- 2.30.2