Fix RNG bugs from upgrade to C++17

staticRandomShuffle now uses its own tiny impl of the deprecated std::random_shuffle, producing identical results in testing
This commit is contained in:
Kae 2024-08-02 11:53:59 +10:00
parent 53c4dc3491
commit 497c6efc55
2 changed files with 10 additions and 7 deletions

View File

@ -208,8 +208,8 @@ typename Container::value_type Random::randValueFrom(
template <typename Container> template <typename Container>
void Random::shuffle(Container& container) { void Random::shuffle(Container& container) {
size_t max = container.size(); RandomSource random;
std::shuffle(container.begin(), container.end(), URBG<size_t>([max]() { return Random::randUInt(max - 1); })); std::shuffle(container.begin(), container.end(), URBG<size_t>([&]() { return static_cast<size_t>(random.randu64()); }));
} }
} }

View File

@ -134,11 +134,14 @@ private:
template <typename Container, typename T, typename... TL> template <typename Container, typename T, typename... TL>
void staticRandomShuffle(Container& container, T const& d, TL const&... rest) { void staticRandomShuffle(Container& container, T const& d, TL const&... rest) {
int mix = 0; auto begin = container.begin();
size_t max = container.size(); auto end = container.end();
std::shuffle(container.begin(), container.end(), URBG<size_t>([&]() { auto it = begin;
return staticRandomU32Range(0, max - 1, ++mix, d, rest...); for (int i = 1, mix = 0; ++it != end; ++i) {
})); int off = staticRandomU32Range(0, i, ++mix, d, rest...);
if (off != i)
std::swap(*it, *(begin + off));
}
} }
} }