mRandom.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MRANDOM_H_
  23. #define _MRANDOM_H_
  24. #ifndef _PLATFORMASSERT_H_
  25. #include "platform/platformAssert.h"
  26. #endif
  27. //--------------------------------------
  28. /// Base class for random number generators
  29. class MRandomGenerator
  30. {
  31. protected:
  32. MRandomGenerator() :mSeed(-1) {}
  33. S32 mSeed;
  34. public:
  35. virtual ~MRandomGenerator() {}
  36. void setSeed();
  37. S32 getSeed() { return mSeed; }
  38. virtual void setSeed(S32 s) = 0;
  39. virtual U32 randI( void ) = 0; ///< 0..2^31 random number generator
  40. virtual F32 randF( void ); ///< 0.0 .. 1.0 F32 random number generator
  41. S32 randI(S32 i, S32 n); ///< i..n integer random number generator
  42. F32 randF(F32 i, F32 n); ///< i..n F32 random number generator
  43. };
  44. //--------------------------------------
  45. inline F32 MRandomGenerator::randF()
  46. {
  47. // default: multiply by 1/(2^31)
  48. return F32(randI()) * (1.0f / F64(S32_MAX));
  49. }
  50. inline S32 MRandomGenerator::randI(S32 i, S32 n)
  51. {
  52. AssertFatal(i<=n, "MRandomGenerator::randi: inverted range.");
  53. return (S32)(i + (randI() % (n - i + 1)) );
  54. }
  55. inline F32 MRandomGenerator::randF(F32 i, F32 n)
  56. {
  57. AssertFatal(i<=n, "MRandomGenerator::randf: inverted range.");
  58. return (i + (n - i) * randF());
  59. }
  60. //--------------------------------------
  61. /// Linear Congruential Method, the "minimal standard generator"
  62. ///
  63. /// Fast, farly good random numbers (better than using rand)
  64. ///
  65. /// @author Park & Miller, 1988, Comm of the ACM, 31(10), pp. 1192-1201
  66. class MRandomLCG : public MRandomGenerator
  67. {
  68. protected:
  69. static const S32 msQuotient;
  70. static const S32 msRemainder;
  71. public:
  72. MRandomLCG();
  73. MRandomLCG(S32 s);
  74. virtual ~MRandomLCG() {}
  75. static void setGlobalRandSeed(U32 seed);
  76. void setSeed(S32 s);
  77. // using MRandomGenerator::randI;
  78. S32 randI(S32 i, S32 n); ///< i..n integer generator
  79. U32 randI( void );
  80. };
  81. // Solution to "using" problem.
  82. inline S32 MRandomLCG::randI(S32 i, S32 n)
  83. {
  84. return( MRandomGenerator::randI(i,n) );
  85. }
  86. //--------------------------------------
  87. /// Fast, very good random numbers
  88. ///
  89. /// Period = 2^249
  90. ///
  91. /// Kirkpatrick, S., and E. Stoll, 1981; A Very Fast Shift-Register
  92. /// Sequence Random Number Generator, Journal of Computational Physics,
  93. /// V. 40.
  94. ///
  95. /// Maier, W.L., 1991; A Fast Pseudo Random Number Generator,
  96. /// Dr. Dobb's Journal, May, pp. 152 - 157
  97. class MRandomR250: public MRandomGenerator
  98. {
  99. private:
  100. U32 mBuffer[250];
  101. S32 mIndex;
  102. public:
  103. MRandomR250();
  104. MRandomR250(S32 s);
  105. virtual ~MRandomR250() {}
  106. void setSeed(S32 s);
  107. // using MRandomGenerator::randI;
  108. U32 randI();
  109. };
  110. typedef MRandomLCG MRandom;
  111. extern MRandomLCG gRandGen;
  112. #endif //_MRANDOM_H_