2019-07-27 17:36:24 +03:00
|
|
|
//
|
2020-06-12 18:52:38 +03:00
|
|
|
// CRLib - Simple library for STL replacement in private projects.
|
|
|
|
|
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
|
2019-07-27 17:36:24 +03:00
|
|
|
//
|
2020-06-12 18:52:38 +03:00
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
2019-07-27 17:36:24 +03:00
|
|
|
//
|
2020-06-12 18:52:38 +03:00
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
2019-07-27 17:36:24 +03:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <crlib/cr-basic.h>
|
|
|
|
|
|
|
|
|
|
CR_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
// random number generator see: https://github.com/preshing/RandomSequence/
|
|
|
|
|
class Random final : public Singleton <Random> {
|
|
|
|
|
private:
|
2020-06-12 18:52:38 +03:00
|
|
|
uint32 index_, offset_;
|
|
|
|
|
uint64 divider_;
|
2019-07-27 17:36:24 +03:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit Random () {
|
|
|
|
|
const auto base = static_cast <uint32> (time (nullptr));
|
|
|
|
|
const auto offset = base + 1;
|
|
|
|
|
|
2020-06-12 18:52:38 +03:00
|
|
|
index_ = premute (premute (base) + 0x682f0161);
|
|
|
|
|
offset_ = premute (premute (offset) + 0x46790905);
|
|
|
|
|
divider_ = (static_cast <uint64> (1)) << 32;
|
2019-07-27 17:36:24 +03:00
|
|
|
}
|
|
|
|
|
~Random () = default;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
uint32 premute (uint32 index) {
|
|
|
|
|
static constexpr auto prime = 4294967291u;
|
|
|
|
|
|
|
|
|
|
if (index >= prime) {
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
const uint32 residue = (static_cast <uint64> (index) * index) % prime;
|
|
|
|
|
return (index <= prime / 2) ? residue : prime - residue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32 generate () {
|
2020-06-12 18:52:38 +03:00
|
|
|
return premute ((premute (index_++) + offset_) ^ 0x5bf03635);
|
2019-07-27 17:36:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
template <typename U> U int_ (U low, U high) {
|
2020-06-12 18:52:38 +03:00
|
|
|
return static_cast <U> (generate () * (static_cast <double> (high) - static_cast <double> (low) + 1.0) / divider_ + static_cast <double> (low));
|
2019-07-27 17:36:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float float_ (float low, float high) {
|
2020-06-12 18:52:38 +03:00
|
|
|
return static_cast <float> (generate () * (static_cast <double> (high) - static_cast <double> (low)) / (divider_ - 1) + static_cast <double> (low));
|
2019-07-27 17:36:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename U> bool chance (const U max, const U maxChance = 100) {
|
|
|
|
|
return int_ <U> (0, maxChance) < max;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// expose global random generator
|
2020-02-08 00:03:52 +03:00
|
|
|
CR_EXPOSE_GLOBAL_SINGLETON (Random, rg);
|
2019-07-27 17:36:24 +03:00
|
|
|
|
2020-06-12 18:52:38 +03:00
|
|
|
CR_NAMESPACE_END
|