// Strategic-layer RNG interface. // // Every roll in the strategic simulation (tech-tree race gating, research completion, // lab accidents, probabilistic jumps, ...) draws from one server-owned generator so that // lockstep peers stay in sync. The sim formulas in this module never own a generator; // they take an IRandom& so tests can inject a scripted sequence and the real engine can // inject its MT19937-compatible generator (implemented elsewhere, under src/mars/). #pragma once #include namespace sots::sim { struct IRandom { virtual ~IRandom() = default; // Uniform float in [0, 1] INCLUSIVE: the generator's unit mapping divides by // 2^32 - 1, and the value is narrowed to a 32-bit float before any consumer // compares it (mars::rng::MT19937::next_float). virtual float NextFloat() = 0; // Uniform integer in [0, n] INCLUSIVE (mask-and-reject; the mask covers n, not // n - 1). n == 0 returns 0 and still consumes one word. virtual std::uint32_t NextIntInclusive(std::uint32_t n) = 0; // The raw tempered word, no mapping. A handful of sites take it directly -- the // random-unit-vector helper a failed probabilistic jump uses is one -- and a // reimplementation has to consume the same word to stay on the same stream. virtual std::uint32_t NextUInt32() = 0; }; } // namespace sots::sim