|
Freeciv-3.1
|
Go to the source code of this file.
Data Structures | |
| struct | RANDOM_STATE |
Macros | |
| #define | fc_rand(_size) fc_rand_debug((_size), "fc_rand", __FC_LINE__, __FILE__) |
| #define | fc_randomly(_seed, _size) fc_randomly_debug((_seed), (_size), "fc_randomly", __FC_LINE__, __FILE__) |
Typedefs | |
| typedef uint32_t | RANDOM_TYPE |
Functions | |
| RANDOM_TYPE | fc_rand_debug (RANDOM_TYPE size, const char *called_as, int line, const char *file) |
| void | fc_srand (RANDOM_TYPE seed) |
| void | fc_rand_uninit (void) |
| bool | fc_rand_is_init (void) |
| RANDOM_STATE | fc_rand_state (void) |
| void | fc_rand_set_state (RANDOM_STATE state) |
| void | test_random1 (int n) |
| RANDOM_TYPE | fc_randomly_debug (RANDOM_TYPE seed, RANDOM_TYPE size, const char *called_as, int line, const char *file) |
| #define fc_rand | ( | _size | ) | fc_rand_debug((_size), "fc_rand", __FC_LINE__, __FILE__) |
| #define fc_randomly | ( | _seed, | |
| _size | |||
| ) | fc_randomly_debug((_seed), (_size), "fc_randomly", __FC_LINE__, __FILE__) |
| typedef uint32_t RANDOM_TYPE |
| RANDOM_TYPE fc_rand_debug | ( | RANDOM_TYPE | size, |
| const char * | called_as, | ||
| int | line, | ||
| const char * | file | ||
| ) |
Returns a new random value from the sequence, in the interval 0 to (size-1) inclusive, and updates global state for next call. This means that if size <= 1 the function will always return 0.
Once we calculate new_rand below uniform (we hope) between 0 and MAX_UINT32 inclusive, need to reduce to required range. Using modulus is bad because generators like this are generally less random for their low-significance bits, so this can give poor results when 'size' is small. Instead want to divide the range 0..MAX_UINT32 into (size) blocks, each with (divisor) values, and for any remainder, repeat the calculation of new_rand. Then: return_val = new_rand / divisor; Will repeat for new_rand > max, where: max = size * divisor - 1 Then max <= MAX_UINT32 implies size * divisor <= (MAX_UINT32+1) thus divisor <= (MAX_UINT32+1)/size
Need to calculate this divisor. Want divisor as large as possible given above constraint, but it doesn't hurt us too much if it is a bit smaller (just have to repeat more often). Calculation exactly as above is complicated by fact that (MAX_UINT32+1) may not be directly representable in type RANDOM_TYPE, so we do instead: divisor = MAX_UINT32/size
| bool fc_rand_is_init | ( | void | ) |
Return whether the current state has been initialized.
Definition at line 167 of file rand.c.
Referenced by init_game_seed(), and sg_save_random().
| void fc_rand_set_state | ( | RANDOM_STATE | state | ) |
Replace current rand_state with user-supplied; eg for save/restore. Caller should take care to set state.is_init beforehand if necessary.
Definition at line 196 of file rand.c.
Referenced by map_fractal_generate(), sg_load_random(), sg_load_random(), sg_load_sanitycheck(), sg_load_sanitycheck(), and test_random1().
| RANDOM_STATE fc_rand_state | ( | void | ) |
Return a copy of the current rand_state; eg for save/restore.
Definition at line 175 of file rand.c.
Referenced by loaddata_new(), loaddata_new(), map_fractal_generate(), sg_load_random(), sg_load_random(), sg_save_random(), and test_random1().
| void fc_rand_uninit | ( | void | ) |
| RANDOM_TYPE fc_randomly_debug | ( | RANDOM_TYPE | seed, |
| RANDOM_TYPE | size, | ||
| const char * | called_as, | ||
| int | line, | ||
| const char * | file | ||
| ) |
| void fc_srand | ( | RANDOM_TYPE | seed | ) |
Initialize the generator; see comment at top of file.
Definition at line 128 of file rand.c.
Referenced by client_main(), fcmp_init(), init_game_seed(), and map_fractal_generate().
| void test_random1 | ( | int | n | ) |
Test one aspect of randomness, using n numbers. Reports results to LOG_TEST; with good randomness, behaviourchange and behavioursame should be about the same size. Tests current random state; saves and restores state, so can call without interrupting current sequence.
Definition at line 220 of file rand.c.
Referenced by srv_ready().