diff options
Diffstat (limited to 'src/common/random.c')
-rw-r--r-- | src/common/random.c | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/src/common/random.c b/src/common/random.c index ba70a5c1d..263c541b9 100644 --- a/src/common/random.c +++ b/src/common/random.c @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team - * Copyright (C) Athena Dev Teams + * Copyright (C) 2012-2020 Hercules Dev Team + * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ #include "common/timer.h" // gettick #include <mt19937ar/mt19937ar.h> // init_genrand, genrand_int32, genrand_res53 +#include <stdlib.h> #if defined(WIN32) # include "common/winapi.h" @@ -35,9 +36,15 @@ # include <unistd.h> #endif +/** @file + * Implementation of the random number generator interface. + */ + +static struct rnd_interface rnd_s; +struct rnd_interface *rnd; -/// Initializes the random number generator with an appropriate seed. -void rnd_init(void) +/// @copydoc rnd_interface::init() +static void rnd_init(void) { unsigned long seed = (unsigned long)timer->gettick(); seed += (unsigned long)time(NULL); @@ -53,53 +60,64 @@ void rnd_init(void) #endif // HAVE_GETTID #endif init_genrand(seed); + + // Also initialize the stdlib rng, just in case it's used somewhere. + srand((unsigned int)seed); } +/// @copydoc rnd_interface::final() +static void rnd_final(void) +{ +} -/// Initializes the random number generator. -void rnd_seed(uint32 seed) +/// @copydoc rnd_interface::seed() +static void rnd_seed(uint32 seed) { init_genrand(seed); } - -/// Generates a random number in the interval [0, SINT32_MAX] -int32 rnd(void) +/// @copydoc rnd_interface::random() +static int32 rnd_random(void) { return (int32)genrand_int31(); } - -/// Generates a random number in the interval [0, dice_faces) -/// NOTE: interval is open ended, so dice_faces is excluded (unless it's 0) -uint32 rnd_roll(uint32 dice_faces) +/// @copydoc rnd_interface::roll() +static uint32 rnd_roll(uint32 dice_faces) { - return (uint32)(rnd_uniform()*dice_faces); + return (uint32)(rnd->uniform()*dice_faces); } - -/// Generates a random number in the interval [min, max] -/// Returns min if range is invalid. -int32 rnd_value(int32 min, int32 max) +/// @copydoc rnd_interface::value() +static int32 rnd_value(int32 min, int32 max) { - if( min >= max ) + if (min >= max) return min; - return min + (int32)(rnd_uniform()*(max-min+1)); + return min + (int32)(rnd->uniform()*(max-min+1)); } - -/// Generates a random number in the interval [0.0, 1.0) -/// NOTE: interval is open ended, so 1.0 is excluded -double rnd_uniform(void) +/// @copydoc rnd_interface::uniform() +static double rnd_uniform(void) { return ((uint32)genrand_int32())*(1.0/4294967296.0);// divided by 2^32 } - -/// Generates a random number in the interval [0.0, 1.0) with 53-bit resolution -/// NOTE: interval is open ended, so 1.0 is excluded -/// NOTE: 53 bits is the maximum precision of a double -double rnd_uniform53(void) +/// @copydoc rnd_interface::uniform53() +static double rnd_uniform53(void) { return genrand_res53(); } + +/// Interface base initialization. +void rnd_defaults(void) +{ + rnd = &rnd_s; + rnd->init = rnd_init; + rnd->final = rnd_final; + rnd->seed = rnd_seed; + rnd->random = rnd_random; + rnd->roll = rnd_roll; + rnd->value = rnd_value; + rnd->uniform = rnd_uniform; + rnd->uniform53 = rnd_uniform53; +} |