#pragma once #include "h-basic.hpp" #include "seed_fwd.hpp" #include #include /**** Available constants ****/ /* * Random Number Generator -- Degree of "complex" RNG -- see "misc.c" * This value is hard-coded at 63 for a wide variety of reasons. */ #define RAND_DEG 63 /**** Available Variables ****/ /** * Change to "quick" RNG, using the given seed. */ void set_quick_rng(seed_t const &seed); /** * Change to "complex" RNG which uses the "non-deterministic" seed. */ void set_complex_rng(); /** * Get a copy of the state of the "complex" RNG. */ std::string get_complex_rng_state(); /** * Set the state of the "complex" RNG. The given array must have * been previously obtained via the get_complex_rng_state() function. */ void set_complex_rng_state(std::string const &state); /**** Available Functions ****/ void Rand_state_init(); s16b randnor(int mean, int stand); s32b damroll(s16b num, s16b sides); s32b maxroll(s16b num, s16b sides); /** * Evaluate to "true" p percent of the time. */ bool magik(s32b p); /* * Generates a random long integer X where 0<=X typename C::const_iterator uniform_element(C const &c) { assert(!c.empty()); return std::next(std::cbegin(c), rand_int(c.size())); } /** * Choose a random element in from the given container. * The container, C, must fulfill the Container concept * whose iterators fulfill the RandomIterator concept. **/ template typename C::iterator uniform_element(C &c) { assert(!c.empty()); return std::next(std::begin(c), rand_int(c.size())); } /** * Shuffle contents of given random-access container. */ template void shuffle(C &c) { if (c.empty()) { return; } auto n = c.size(); for (auto i = n - 1; i > 0; i--) { std::swap(c[i], c[rand_int(i + 1)]); } }