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 
00023 struct Randomizer {
00025   uint32 state[2];
00026 
00027   uint32 Next();
00028   uint32 Next(uint32 max);
00029   void SetSeed(uint32 seed);
00030 };
00031 extern Randomizer _random; 
00032 extern Randomizer _interactive_random; 
00033 
00035 struct SavedRandomSeeds {
00036   Randomizer random;
00037   Randomizer interactive_random;
00038 };
00039 
00044 static inline void SaveRandomSeeds(SavedRandomSeeds *storage)
00045 {
00046   storage->random = _random;
00047   storage->interactive_random = _interactive_random;
00048 }
00049 
00054 static inline void RestoreRandomSeeds(const SavedRandomSeeds &storage)
00055 {
00056   _random = storage.random;
00057   _interactive_random = storage.interactive_random;
00058 }
00059 
00060 void SetRandomSeed(uint32 seed);
00061 #ifdef RANDOM_DEBUG
00062   #ifdef __APPLE__
00063     #define OTTD_Random() DoRandom(__LINE__, __FILE__)
00064   #else
00065     #define Random() DoRandom(__LINE__, __FILE__)
00066   #endif
00067   uint32 DoRandom(int line, const char *file);
00068   #define RandomRange(max) DoRandomRange(max, __LINE__, __FILE__)
00069   uint32 DoRandomRange(uint32 max, int line, const char *file);
00070 #else
00071   static inline uint32 Random()
00072   {
00073     return _random.Next();
00074   }
00075 
00076   static inline uint32 RandomRange(uint32 max)
00077   {
00078     return _random.Next(max);
00079   }
00080 #endif
00081 
00082 static inline uint32 InteractiveRandom()
00083 {
00084   return _interactive_random.Next();
00085 }
00086 
00087 static inline uint32 InteractiveRandomRange(uint32 max)
00088 {
00089   return _interactive_random.Next(max);
00090 }
00091 
00107 static inline bool Chance16I(const uint a, const uint b, const uint32 r)
00108 {
00109   assert(b != 0);
00110   return (((uint16)r * b + b / 2) >> 16) < a;
00111 }
00112 
00123 #ifdef RANDOM_DEBUG
00124   #define Chance16(a, b) Chance16I(a, b, DoRandom(__LINE__, __FILE__))
00125 #else
00126 static inline bool Chance16(const uint a, const uint b)
00127 {
00128   return Chance16I(a, b, Random());
00129 }
00130 #endif /* RANDOM_DEBUG */
00131 
00147 #ifdef RANDOM_DEBUG
00148   #define Chance16R(a, b, r) (r = DoRandom(__LINE__, __FILE__), Chance16I(a, b, r))
00149 #else
00150 static inline bool Chance16R(const uint a, const uint b, uint32 &r)
00151 {
00152   r = Random();
00153   return Chance16I(a, b, r);
00154 }
00155 #endif /* RANDOM_DEBUG */
00156 
00157 #endif /* RANDOM_FUNC_HPP */