# random_func.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifndef RANDOM_FUNC_HPP
    00013 #define RANDOM_FUNC_HPP
    00014
    00015 #if defined(__APPLE__)
    00016   /* Apple already has Random declared */
    00017   #define Random OTTD_Random
    00018 #endif /* __APPLE__ */
    00019
    00020 /**************
    00021  * Warning: DO NOT enable this unless you understand what it does
    00022  *
    00023  * If enabled, in a network game all randoms will be dumped to the
    00024  *  stdout if the first client joins (or if you are a client). This
    00025  *  is to help finding desync problems.
    00026  *
    00027  * Warning: DO NOT enable this unless you understand what it does
    00028  **************/
    00029
    00030 //#define RANDOM_DEBUG
    00031
    00032
    00036 struct Randomizer {
    00038   uint32 state[2];
    00039
    00040   uint32 Next();
    00041   uint32 Next(uint32 max);
    00042   void SetSeed(uint32 seed);
    00043 };
    00044 extern Randomizer _random;
    00045 extern Randomizer _interactive_random;
    00046
    00048 struct SavedRandomSeeds {
    00049   Randomizer random;
    00050   Randomizer interactive_random;
    00051 };
    00052
    00057 static inline void SaveRandomSeeds(SavedRandomSeeds *storage)
    00058 {
    00059   storage->random = _random;
    00060   storage->interactive_random = _interactive_random;
    00061 }
    00062
    00067 static inline void RestoreRandomSeeds(const SavedRandomSeeds &storage)
    00068 {
    00069   _random = storage.random;
    00070   _interactive_random = storage.interactive_random;
    00071 }
    00072
    00073 void SetRandomSeed(uint32 seed);
    00074 #ifdef RANDOM_DEBUG
    00075   #ifdef __APPLE__
    00076     #define OTTD_Random() DoRandom(__LINE__, __FILE__)
    00077   #else
    00078     #define Random() DoRandom(__LINE__, __FILE__)
    00079   #endif
    00080   uint32 DoRandom(int line, const char *file);
    00081   #define RandomRange(max) DoRandomRange(max, __LINE__, __FILE__)
    00082   uint32 DoRandomRange(uint32 max, int line, const char *file);
    00083 #else
    00084   static FORCEINLINE uint32 Random()
    00085   {
    00086     return _random.Next();
    00087   }
    00088
    00089   static FORCEINLINE uint32 RandomRange(uint32 max)
    00090   {
    00091     return _random.Next(max);
    00092   }
    00093 #endif
    00094
    00095 static FORCEINLINE uint32 InteractiveRandom()
    00096 {
    00097   return _interactive_random.Next();
    00098 }
    00099
    00100 static FORCEINLINE uint32 InteractiveRandomRange(uint32 max)
    00101 {
    00102   return _interactive_random.Next(max);
    00103 }
    00104
    00120 static FORCEINLINE bool Chance16I(const uint a, const uint b, const uint32 r)
    00121 {
    00122   assert(b != 0);
    00123   return (((uint16)r * b + b / 2) >> 16) < a;
    00124 }
    00125
    00136 #ifdef RANDOM_DEBUG
    00137   #define Chance16(a, b) Chance16I(a, b, DoRandom(__LINE__, __FILE__))
    00138 #else
    00139 static FORCEINLINE bool Chance16(const uint a, const uint b)
    00140 {
    00141   return Chance16I(a, b, Random());
    00142 }
    00143 #endif /* RANDOM_DEBUG */
    00144
    00160 #ifdef RANDOM_DEBUG
    00161   #define Chance16R(a, b, r) (r = DoRandom(__LINE__, __FILE__), Chance16I(a, b, r))
    00162 #else
    00163 static FORCEINLINE bool Chance16R(const uint a, const uint b, uint32 &r)
    00164 {
    00165   r = Random();
    00166   return Chance16I(a, b, r);
    00167 }
    00168 #endif /* RANDOM_DEBUG */
    00169
    00170 #endif /* RANDOM_FUNC_HPP */