ht is 0.");
return;
}
}
}; //End of namespace Lunacia.
Random.cpp
#include "Random.h"
namespace Lunacia
{
//Random
std::mt19937_64 Random::baseGener;
LARGE_INTEGER Random::sysTime;
std::atomic<uint64_t> Random::ranCount = 0LL;
const uint64_t Random::RandBase = 100000000LL;
Random::Random()
{
Random::Init();
}
Random::~Random()
{
Reset();
}
void Random::Init(bool isPRNG, uint64_t inSeed)
{
if (isPRNG)
{
baseGener.seed(inSeed);
return;
}
//QueryPerformanceCounter
LARGE_INTEGER _freq;
LARGE_INTEGER _count;
QueryPerformanceFrequency(&_freq);
QueryPerformanceCounter(&_count);
sysTime.QuadPart = _count.QuadPart * 1000000 / _freq.QuadPart;
uint64_t seed = sysTime.QuadPart;
if (seed == 0LL)
{
WarningThrow("QueryPerformanceFrequency function is nonsupport.");
//Initializating the seed by time.
{
using namespace std::chrono;
time_point<system_clock, milliseconds> tp = \
time_point_cast<milliseconds>(system_clock::now());
auto tmp = duration_cast<milliseconds>(tp.time_since_epoch());
seed = tmp.count();
}
}
baseGener.seed(seed);
}
void Random::Reset()
{
baseGener.seed();
ranCount = 0LL;
}
uint64_t Random::GetRandNum()
{
const uint64_t& ret = baseGener();
SyncSeed();
return ret;
}
void Random::SyncSeed()
{
static const uint64_t& period =
(static_cast<uint64_t>(std::powl(2, (baseGener.word_size * (baseGener.state_size - 1))) - 1)) / baseGener.state_size;
if (++ranCount >= period)
{
ranCount = 0LL;
Init();
}
}
//RandomAvg
std::uniform_int_distribution<uint64_t> RandomAvg::avgNum;
RandomAvg::RandomAvg()
{
RandomAvg::Init();
}
RandomAvg::~RandomAvg()
{
RandomAvg::Reset();
}
void RandomAvg::Init()
{
Random::Init();
}
void RandomAvg::Reset()
{
RandomAvg::avgNum.reset();
}
uint64_t RandomAvg::GetRandNum()
{
baseGener.discard(sysTime.LowPart % baseGener.state_size);
SyncSeed();
return avgNum(baseGener);
}
//Return [min, max).
uint64_t RandomAvg::GetRandNum(const uint64_t& min, const uint64_t& max)
{
if (min >= max)
{
ErrorThrow(
"RandomAvg::GetAveNum The minimum cannot be greater than or equal to the maximum. "
"min: " + std::to_string(min) + "; max: " + std::to_string(max) + "."
);
return 0LL;
}
return GetRandNum() % (max - min) + min;
}
bool RandomAvg::HitProbability(const double& prob)
{
if (prob >= 1.0)
{
return true;
}
if (prob <= 0.0)
{
return false;
}
const uint64_t randNum = GetRandNum(0, RandBase) + 1;
uint64_t exp = static_cast<uint64_t>(prob * RandBase);
return randNum <= exp;
}
uint64_t RandomAvg::HitExpectation(const double & prob)
{
if (static_cast<int>(prob) >= 1)
{
return 1;
}
if (prob <= 0.0)
{
return 0;
}
uint64_t rand = GetRandNum(0, RandBase);
return static_cast<uint64_t>((rand + 1) * (1.0 / prob)) / RandBase + 1;
}
//Norm
RandomNorm::RandomNorm() :
RandomNorm(0.0, 1.0)
{
}
RandomNorm::RandomNorm(long double avg, long double stdDev)
{
Init(avg, stdDev);
}
RandomNorm::~RandomNorm()
{
Clear();
}
void RandomNorm::Init(const long double& avg, const long double& stdDev)
{
_avg = avg;
_stdDev = stdDev;
Random::Init();
delete ptrNormNum;