diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/random_func.cpp | 46 | ||||
-rw-r--r-- | src/core/random_func.hpp | 39 |
2 files changed, 53 insertions, 32 deletions
diff --git a/src/core/random_func.cpp b/src/core/random_func.cpp index b0939229e..f74309a6e 100644 --- a/src/core/random_func.cpp +++ b/src/core/random_func.cpp @@ -6,20 +6,26 @@ #include "random_func.hpp" #include "bitmath_func.hpp" -uint32 _random_seeds[2][2]; +Randomizer _random, _interactive_random; -uint32 InteractiveRandom() +uint32 Randomizer::Next() { - const uint32 s = _random_seeds[1][0]; - const uint32 t = _random_seeds[1][1]; + const uint32 s = this->state[0]; + const uint32 t = this->state[1]; - _random_seeds[1][0] = s + ROR(t ^ 0x1234567F, 7) + 1; - return _random_seeds[1][1] = ROR(s, 3) - 1; + this->state[0] = s + ROR(t ^ 0x1234567F, 7) + 1; + return this->state[1] = ROR(s, 3) - 1; } -uint InteractiveRandomRange(uint max) +uint32 Randomizer::Next(uint16 max) { - return GB(InteractiveRandom(), 0, 16) * max >> 16; + return GB(this->Next(), 0, 16) * max >> 16; +} + +void Randomizer::SetSeed(uint32 seed) +{ + this->state[0] = seed; + this->state[1] = seed; } #ifdef MERSENNE_TWISTER @@ -119,28 +125,21 @@ uint32 Random() #else /* MERSENNE_TWISTER */ void SetRandomSeed(uint32 seed) { - _random_seeds[0][0] = seed; - _random_seeds[0][1] = seed; - _random_seeds[1][0] = seed * 0x1234567; - _random_seeds[1][1] = _random_seeds[1][0]; + _random.SetSeed(seed); + _interactive_random.SetSeed(seed * 0x1234567); } #ifdef RANDOM_DEBUG #include "../network/network_data.h" uint32 DoRandom(int line, const char *file) { - if (_networking && (DEREF_CLIENT(0)->status != STATUS_INACTIVE || !_network_server)) + if (_networking && (DEREF_CLIENT(0)->status != STATUS_INACTIVE || !_network_server)) { printf("Random [%d/%d] %s:%d\n",_frame_counter, (byte)_current_player, file, line); -#else /* RANDOM_DEBUG */ -uint32 Random() -{ -#endif /* RANDOM_DEBUG */ - const uint32 s = _random_seeds[0][0]; - const uint32 t = _random_seeds[0][1]; + } - _random_seeds[0][0] = s + ROR(t ^ 0x1234567F, 7) + 1; - return _random_seeds[0][1] = ROR(s, 3) - 1; + return _random->Next() } +#endif /* RANDOM_DEBUG */ #endif /* MERSENNE_TWISTER */ #if defined(RANDOM_DEBUG) && !defined(MERSENNE_TWISTER) @@ -148,9 +147,4 @@ uint DoRandomRange(uint max, int line, const char *file) { return GB(DoRandom(line, file), 0, 16) * max >> 16; } -#else /* RANDOM_DEBUG & !MERSENNE_TWISTER */ -uint RandomRange(uint max) -{ - return GB(Random(), 0, 16) * max >> 16; -} #endif /* RANDOM_DEBUG & !MERSENNE_TWISTER */ diff --git a/src/core/random_func.hpp b/src/core/random_func.hpp index f3d35d987..d941f283c 100644 --- a/src/core/random_func.hpp +++ b/src/core/random_func.hpp @@ -27,6 +27,35 @@ // Doesn't work with network yet. // #define MERSENNE_TWISTER +/** + * Structure to encapsulate the pseudo random number generators. + */ +struct Randomizer { + /** The state of the randomizer */ + uint32 state[2]; + + /** + * Generate the next pseudo random number + * @return the random number + */ + uint32 Next(); + + /** + * Generate the next pseudo random number scaled to max + * @param max the maximum value of the returned random number + * @return the random number + */ + uint32 Next(uint16 max); + + /** + * (Re)set the state of the random number generator. + * @param seed the new state + */ + void SetSeed(uint32 seed); +}; +extern Randomizer _random; ///< Random used in the game state calculations +extern Randomizer _interactive_random; ///< Random used every else where is does not (directly) influence the game state + void SetRandomSeed(uint32 seed); #ifdef RANDOM_DEBUG #define Random() DoRandom(__LINE__, __FILE__) @@ -34,12 +63,12 @@ void SetRandomSeed(uint32 seed); #define RandomRange(max) DoRandomRange(max, __LINE__, __FILE__) uint DoRandomRange(uint max, int line, const char *file); #else - uint32 Random(); - uint RandomRange(uint max); + static inline uint32 Random() { return _random.Next(); } + static inline uint32 RandomRange(uint16 max) { return _random.Next(max); } #endif -uint32 InteractiveRandom(); // Used for random sequences that are not the same on the other end of the multiplayer link -uint InteractiveRandomRange(uint max); +static inline uint32 InteractiveRandom() { return _interactive_random.Next(); } +static inline uint32 InteractiveRandomRange(uint16 max) { return _interactive_random.Next(max); } /** * Checks if a given randomize-number is below a given probability. @@ -100,6 +129,4 @@ static inline bool Chance16R(const uint a, const uint b, uint32 &r) return Chance16I(a, b, r); } -extern uint32 _random_seeds[2][2]; - #endif /* RANDOM_FUNC_HPP */ |