OpenTTD Source 20241224-master-gee860a5c8e
random_func.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD 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.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#ifndef RANDOM_FUNC_HPP
11#define RANDOM_FUNC_HPP
12
19static constexpr uint32_t ScaleToLimit(uint32_t value, uint32_t limit)
20{
21 return ((uint64_t)value * (uint64_t)limit) >> 32;
22}
23
27struct Randomizer {
29 uint32_t state[2];
30
31 uint32_t Next();
32 void SetSeed(uint32_t seed);
33
40 inline uint32_t Next(uint32_t limit) { return ScaleToLimit(this->Next(), limit); }
41};
42extern Randomizer _random;
44
47 Randomizer random;
48 Randomizer interactive_random;
49};
50
55inline void SaveRandomSeeds(SavedRandomSeeds *storage)
56{
57 storage->random = _random;
58 storage->interactive_random = _interactive_random;
59}
60
65inline void RestoreRandomSeeds(const SavedRandomSeeds &storage)
66{
67 _random = storage.random;
68 _interactive_random = storage.interactive_random;
69}
70
71void SetRandomSeed(uint32_t seed);
72#ifdef RANDOM_DEBUG
73 uint32_t Random(const std::source_location location = std::source_location::current());
74#else
75 inline uint32_t Random([[maybe_unused]] const std::source_location location = std::source_location::current())
76 {
77 return _random.Next();
78 }
79#endif
80
88inline uint32_t RandomRange(uint32_t limit, const std::source_location location = std::source_location::current())
89{
90 return ScaleToLimit(Random(location), limit);
91}
92
93inline uint32_t InteractiveRandom()
94{
96}
97
98inline uint32_t InteractiveRandomRange(uint32_t limit)
99{
100 return _interactive_random.Next(limit);
101}
102
118inline bool Chance16I(const uint32_t a, const uint32_t b, const uint32_t r)
119{
120 assert(b != 0);
121 return (((uint16_t)r * b + b / 2) >> 16) < a;
122}
123
134inline bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location = std::source_location::current())
135{
136 return Chance16I(a, b, Random(location));
137}
138
154inline bool Chance16R(const uint32_t a, const uint32_t b, uint32_t &r, const std::source_location location = std::source_location::current())
155{
156 r = Random(location);
157 return Chance16I(a, b, r);
158}
159
160void RandomBytesWithFallback(std::span<uint8_t> buf);
161
162#endif /* RANDOM_FUNC_HPP */
Randomizer _random
Random used in the game state calculations.
void RandomBytesWithFallback(std::span< uint8_t > buf)
Fill the given buffer with random bytes.
static constexpr uint32_t ScaleToLimit(uint32_t value, uint32_t limit)
Scale a uint32_t number to be within the range [0,limit).
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
bool Chance16I(const uint32_t a, const uint32_t b, const uint32_t r)
Checks if a given randomize-number is below a given probability.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
Randomizer _interactive_random
Random used everywhere else, where it does not (directly) influence the game state.
bool Chance16R(const uint32_t a, const uint32_t b, uint32_t &r, const std::source_location location=std::source_location::current())
Flips a coin with a given probability and saves the randomize-number in a variable.
void SaveRandomSeeds(SavedRandomSeeds *storage)
Saves the current seeds.
void SetRandomSeed(uint32_t seed)
(Re)set the state of the random number generators.
void RestoreRandomSeeds(const SavedRandomSeeds &storage)
Restores previously saved seeds.
Structure to encapsulate the pseudo random number generators.
void SetSeed(uint32_t seed)
(Re)set the state of the random number generator.
uint32_t state[2]
The state of the randomizer.
uint32_t Next()
Generate the next pseudo random number.
uint32_t Next(uint32_t limit)
Generate the next pseudo random number scaled to limit, excluding limit itself.
Stores the state of all random number generators.