mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-01-30 15:00:13 -05:00
replace MT RNG with PCG
This commit is contained in:
parent
7df9641297
commit
12e7ea2f9f
@ -1,36 +1,55 @@
|
||||
#include "random.hpp"
|
||||
|
||||
#include <bit>
|
||||
#include <random>
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <boost/random/uniform_int_distribution.hpp>
|
||||
#include <boost/random/uniform_real_distribution.hpp>
|
||||
#include <cassert>
|
||||
|
||||
static bool init = false;
|
||||
static boost::random::mt19937 generator;
|
||||
static uint64_t state = 0;
|
||||
const uint64_t multiplier = 6364136223846793005ULL;
|
||||
const uint64_t increment = 11634580027462260723ULL;
|
||||
|
||||
//Initialize with seed specified
|
||||
void Random_Init(uint32_t seed) {
|
||||
void Random_Init(uint64_t seed) {
|
||||
init = true;
|
||||
generator = boost::random::mt19937{seed};
|
||||
state = seed;
|
||||
}
|
||||
|
||||
uint32_t next32() {
|
||||
if (!init) {
|
||||
//No seed given, get a random number from device to seed
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
uint64_t seed = static_cast<uint64_t>(std::random_device{}());
|
||||
#else
|
||||
uint64_t seed = static_cast<uint64_t>(std::hash<std::string>{}(std::to_string(rand())));
|
||||
#endif
|
||||
Random_Init(seed);
|
||||
}
|
||||
|
||||
state = state * multiplier + increment;
|
||||
uint32_t xorshifted = static_cast<uint32_t>(((state >> 18) ^ state) >> 27);
|
||||
uint32_t rot = static_cast<int>(state >> 59);
|
||||
return std::rotr(xorshifted, rot);
|
||||
}
|
||||
|
||||
//Returns a random integer in range [min, max-1]
|
||||
uint32_t Random(int min, int max) {
|
||||
if (!init) {
|
||||
//No seed given, get a random number from device to seed
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
const auto seed = static_cast<uint32_t>(std::random_device{}());
|
||||
#else
|
||||
uint32_t seed = static_cast<uint32_t>(std::hash<std::string>{}(std::to_string(rand())));
|
||||
#endif
|
||||
Random_Init(seed);
|
||||
if (min == max) {
|
||||
return min;
|
||||
}
|
||||
assert(max > min);
|
||||
|
||||
uint32_t n = max - min;
|
||||
uint32_t cutoff = UINT32_MAX - UINT32_MAX % static_cast<uint32_t>(n);
|
||||
for (;;) {
|
||||
uint32_t r = next32();
|
||||
if (r <= cutoff) {
|
||||
return min + r % n;
|
||||
}
|
||||
}
|
||||
boost::random::uniform_int_distribution<uint32_t> distribution(min, max-1);
|
||||
return distribution(generator);
|
||||
}
|
||||
|
||||
//Returns a random floating point number in [0.0, 1.0]
|
||||
double RandomDouble() {
|
||||
boost::random::uniform_real_distribution<double> distribution(0.0, 1.0);
|
||||
return distribution(generator);
|
||||
return ldexp(next32(), -32);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
void Random_Init(uint32_t seed);
|
||||
void Random_Init(uint64_t seed);
|
||||
uint32_t Random(int min, int max);
|
||||
double RandomDouble();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user