replace MT RNG with PCG

This commit is contained in:
Demur Rumed 2025-01-29 23:57:03 +00:00
parent 7df9641297
commit 12e7ea2f9f
2 changed files with 38 additions and 19 deletions

View File

@ -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);
}

View File

@ -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();