OpenTTD Source  20241108-master-g80f628063a
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 
19 static constexpr uint32_t ScaleToLimit(uint32_t value, uint32_t limit)
20 {
21  return ((uint64_t)value * (uint64_t)limit) >> 32;
22 }
23 
27 struct 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 };
42 extern Randomizer _random;
44 
47  Randomizer random;
48  Randomizer interactive_random;
49 };
50 
55 inline void SaveRandomSeeds(SavedRandomSeeds *storage)
56 {
57  storage->random = _random;
58  storage->interactive_random = _interactive_random;
59 }
60 
65 inline void RestoreRandomSeeds(const SavedRandomSeeds &storage)
66 {
67  _random = storage.random;
68  _interactive_random = storage.interactive_random;
69 }
70 
71 void 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 
88 inline uint32_t RandomRange(uint32_t limit, const std::source_location location = std::source_location::current())
89 {
90  return ScaleToLimit(Random(location), limit);
91 }
92 
93 inline uint32_t InteractiveRandom()
94 {
95  return _interactive_random.Next();
96 }
97 
98 inline uint32_t InteractiveRandomRange(uint32_t limit)
99 {
100  return _interactive_random.Next(limit);
101 }
102 
118 inline 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 
134 inline 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 
154 inline 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 
160 void RandomBytesWithFallback(std::span<uint8_t> buf);
161 
162 #endif /* RANDOM_FUNC_HPP */
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:37
void RandomBytesWithFallback(std::span< uint8_t > buf)
Fill the given buffer with random bytes.
Definition: random_func.cpp:95
static constexpr uint32_t ScaleToLimit(uint32_t value, uint32_t limit)
Scale a uint32_t number to be within the range [0,limit).
Definition: random_func.hpp:19
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.
Definition: random_func.hpp:88
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.
Definition: random_func.cpp:37
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.
Definition: random_func.hpp:55
void SetRandomSeed(uint32_t seed)
(Re)set the state of the random number generators.
Definition: random_func.cpp:66
void RestoreRandomSeeds(const SavedRandomSeeds &storage)
Restores previously saved seeds.
Definition: random_func.hpp:65
Structure to encapsulate the pseudo random number generators.
Definition: random_func.hpp:27
void SetSeed(uint32_t seed)
(Re)set the state of the random number generator.
Definition: random_func.cpp:56
uint32_t state[2]
The state of the randomizer.
Definition: random_func.hpp:29
uint32_t Next()
Generate the next pseudo random number.
Definition: random_func.cpp:43
uint32_t Next(uint32_t limit)
Generate the next pseudo random number scaled to limit, excluding limit itself.
Definition: random_func.hpp:40
Stores the state of all random number generators.
Definition: random_func.hpp:46