/* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 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; ecb_noinline void 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]; } ecb_noinline void 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 ecb_noinline uint32_t random_number_generator::get_u32 () { return generator::next (); } template ecb_noinline uint64_t random_number_generator::get_u64 () { return (uint64_t (get_u32 ()) << 32U) | get_u32 (); } template ecb_noinline float random_number_generator::get_float () { return this->next () / (float)0x100000000ULL; } template ecb_noinline double 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;