(svn r27950) -Merge: Documentation updates from 1.7 branch
[openttd.git] / src / core / random_func.hpp
blob0c6b8f1ca7f41575002f942d3af6c99b104ba313
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file random_func.hpp Pseudo random number generator. */
12 #ifndef RANDOM_FUNC_HPP
13 #define RANDOM_FUNC_HPP
15 #if defined(__APPLE__)
16 /* Apple already has Random declared */
17 #define Random OTTD_Random
18 #endif /* __APPLE__ */
20 /**
21 * Structure to encapsulate the pseudo random number generators.
23 struct Randomizer {
24 /** The state of the randomizer */
25 uint32 state[2];
27 uint32 Next();
28 uint32 Next(uint32 limit);
29 void SetSeed(uint32 seed);
31 extern Randomizer _random; ///< Random used in the game state calculations
32 extern Randomizer _interactive_random; ///< Random used every else where is does not (directly) influence the game state
34 /** Stores the state of all random number generators */
35 struct SavedRandomSeeds {
36 Randomizer random;
37 Randomizer interactive_random;
40 /**
41 * Saves the current seeds
42 * @param storage Storage for saving
44 static inline void SaveRandomSeeds(SavedRandomSeeds *storage)
46 storage->random = _random;
47 storage->interactive_random = _interactive_random;
50 /**
51 * Restores previously saved seeds
52 * @param storage Storage where SaveRandomSeeds() stored th seeds
54 static inline void RestoreRandomSeeds(const SavedRandomSeeds &storage)
56 _random = storage.random;
57 _interactive_random = storage.interactive_random;
60 void SetRandomSeed(uint32 seed);
61 #ifdef RANDOM_DEBUG
62 #ifdef __APPLE__
63 #define OTTD_Random() DoRandom(__LINE__, __FILE__)
64 #else
65 #define Random() DoRandom(__LINE__, __FILE__)
66 #endif
67 uint32 DoRandom(int line, const char *file);
68 #define RandomRange(limit) DoRandomRange(limit, __LINE__, __FILE__)
69 uint32 DoRandomRange(uint32 limit, int line, const char *file);
70 #else
71 static inline uint32 Random()
73 return _random.Next();
76 /**
77 * Pick a random number between 0 and \a limit - 1, inclusive. That means 0
78 * can be returned and \a limit - 1 can be returned, but \a limit can not be
79 * returned.
80 * @param limit Limit for the range to be picked from.
81 * @return A random number in [0,\a limit).
83 static inline uint32 RandomRange(uint32 limit)
85 return _random.Next(limit);
87 #endif
89 static inline uint32 InteractiveRandom()
91 return _interactive_random.Next();
94 static inline uint32 InteractiveRandomRange(uint32 limit)
96 return _interactive_random.Next(limit);
99 /**
100 * Checks if a given randomize-number is below a given probability.
102 * This function is used to check if the given probability by the fraction of (a/b)
103 * is greater than low 16 bits of the given randomize-number r.
105 * Do not use this function twice on the same random 16 bits as it will yield
106 * the same result. One can use a random number for two calls to Chance16I,
107 * where one call sends the low 16 bits and the other the high 16 bits.
109 * @param a The numerator of the fraction
110 * @param b The denominator of the fraction, must of course not be null
111 * @param r The given randomize-number
112 * @return True if the probability given by r is less or equal to (a/b)
114 static inline bool Chance16I(const uint a, const uint b, const uint32 r)
116 assert(b != 0);
117 return (((uint16)r * b + b / 2) >> 16) < a;
121 * Flips a coin with given probability.
123 * This function returns true with (a/b) probability.
125 * @see Chance16I()
126 * @param a The nominator of the fraction
127 * @param b The denominator of the fraction
128 * @return True with (a/b) probability
130 #ifdef RANDOM_DEBUG
131 #define Chance16(a, b) Chance16I(a, b, DoRandom(__LINE__, __FILE__))
132 #else
133 static inline bool Chance16(const uint a, const uint b)
135 return Chance16I(a, b, Random());
137 #endif /* RANDOM_DEBUG */
140 * Flips a coin with a given probability and saves the randomize-number in a variable.
142 * This function uses the same parameters as Chance16. The third parameter
143 * must be a variable the randomize-number from Random() is saved in.
145 * The low 16 bits of r will already be used and can therefore not be passed to
146 * Chance16I. One can only send the high 16 bits to Chance16I.
148 * @see Chance16I()
149 * @param a The numerator of the fraction
150 * @param b The denominator of the fraction
151 * @param r The variable to save the randomize-number from Random()
152 * @return True in (a/b) percent
154 #ifdef RANDOM_DEBUG
155 #define Chance16R(a, b, r) (r = DoRandom(__LINE__, __FILE__), Chance16I(a, b, r))
156 #else
157 static inline bool Chance16R(const uint a, const uint b, uint32 &r)
159 r = Random();
160 return Chance16I(a, b, r);
162 #endif /* RANDOM_DEBUG */
164 #endif /* RANDOM_FUNC_HPP */