/*
* This file is part of Deliantra, the Roguelike Realtime MMORPG.
*
* Copyright (©) 2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
*
* Deliantra is free software: you can redistribute it and/or modify it under
* the terms of the Affero GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the Affero GNU General Public License
* and the GNU General Public License along with this program. If not, see
* .
*
* The authors can be reached via e-mail to
*/
#include
#include
rand_gen rndm, rmg_rndm;
void noinline
tausworthe_rng::seed (uint32_t seed)
{
state [0] = seed * 69069U; if (state [0] < 2U) state [0] += 2U;
state [1] = state [0] * 69069U; if (state [1] < 8U) state [1] += 8U;
state [2] = state [1] * 69069U; if (state [2] < 16U) state [2] += 16U;
state [3] = state [2] * 69069U; if (state [3] < 128U) state [3] += 128U;
for (int i = 11; --i; )
next ();
}
uint32_t
tausworthe_rng::next ()
{
state [0] = ((state [0] & 0xFFFFFFFEU) << 18U) ^ (((state [0] << 6U) ^ state [0]) >> 13U);
state [1] = ((state [1] & 0xFFFFFFF8U) << 2U) ^ (((state [1] << 2U) ^ state [1]) >> 27U);
state [2] = ((state [2] & 0xFFFFFFF0U) << 7U) ^ (((state [2] << 13U) ^ state [2]) >> 21U);
state [3] = ((state [3] & 0xFFFFFF80U) << 13U) ^ (((state [3] << 3U) ^ state [3]) >> 12U);
return state [0] ^ state [1] ^ state [2] ^ state [3];
}
void noinline
r250521_rng::seed (uint32_t seed)
{
xorshift_rng rng;
rng.seed (seed);
r250.seed_rng (rng);
r521.seed_rng (rng);
}
uint32_t
r250521_rng::next ()
{
return r250.next () ^ r521.next ();
}
template
uint32_t
random_number_generator::get_range (uint32_t num)
{
return (this->next () * (uint64_t)num) >> 32U;
}
template
uint32_t noinline
random_number_generator::get_u32 ()
{
return generator::next ();
}
template
uint64_t noinline
random_number_generator::get_u64 ()
{
return (uint64_t (get_u32 ()) << 32U) | get_u32 ();
}
template
float noinline
random_number_generator::get_float ()
{
return this->next () / (float)0x100000000ULL;
}
template
double noinline
random_number_generator::get_double ()
{
return this->next () / (double)0x100000000ULL;
}
// return a number within (min .. max)
template
int
random_number_generator::get_range (int r_min, int r_max)
{
return r_min + get_range (max (r_max - r_min + 1, 0));
}
template
uint32_t
random_number_generator::poisson (double mean)
{
double g = std::exp (-mean);
uint32_t em = 0;
double t = get_double ();
while (t > g)
{
++em;
t *= get_double ();
}
return em;
}
template struct random_number_generator;
template struct random_number_generator;
template struct random_number_generator;
template struct random_number_generator;
template struct random_number_generator;
template struct random_number_generator;
template struct random_number_generator;
template struct random_number_generator;