Merged changes from branches/supertux-milestone2-grumbel/ to trunk/supertux/
[supertux.git] / src / math / random_generator.hpp
1 // $Id$
2 //
3 // A strong random number generator
4 //
5 // Copyright (C) 2006 Allen King
6 // Copyright (C) 2002 Michael Ringgaard. All rights reserved.
7 // Copyright (C) 1983, 1993 The Regents of the University of California.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
11 // are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright
14 //    notice, this list of conditions and the following disclaimer.
15 // 2. Redistributions in binary form must reproduce the above copyright
16 //    notice, this list of conditions and the following disclaimer in the
17 //    documentation and/or other materials provided with the distribution.
18 // 3. Neither the name of the project nor the names of its contributors
19 //    may be used to endorse or promote products derived from this software
20 //    without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 // ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
26 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 // SUCH DAMAGE.
33
34 #ifndef HEADER_SUPERTUX_MATH_RANDOM_GENERATOR_HPP
35 #define HEADER_SUPERTUX_MATH_RANDOM_GENERATOR_HPP
36
37 class RandomGenerator
38 {
39 private:
40   // Array versions of the above information to make code run faster --
41   // relies on fact that TYPE_i == i.
42   static const int TYPE_0 = 0;   // Linear congruential
43   static const int BREAK_0 = 8;
44   static const int DEG_0 = 0;
45   static const int SEP_0 = 0;
46
47   static const int TYPE_1 = 1;   // x**7 + x**3 + 1
48   static const int BREAK_1 = 32;
49   static const int DEG_1 = 7;
50   static const int SEP_1 = 3;
51
52   static const int TYPE_2 = 2;   // x**15 + x + 1
53   static const int BREAK_2 = 64;
54   static const int DEG_2 = 15;
55   static const int SEP_2 = 1;
56
57   static const int TYPE_3 = 3;   // x**31 + x**3 + 1
58   static const int BREAK_3 = 128;
59   static const int DEG_3 = 31;
60   static const int SEP_3 = 3;
61
62   static const int TYPE_4 = 4;   // x**63 + x + 1
63   static const int BREAK_4 = 256;
64   static const int DEG_4 = 63;
65   static const int SEP_4 = 1;
66
67   static const int MAX_TYPES = 5;     // Max number of types above
68
69   bool initialized;
70   long degrees[MAX_TYPES];
71   long seps [MAX_TYPES];
72   long randtbl[DEG_3 + 1];
73
74   long *fptr;
75   long *rptr;
76
77   long *state;
78   long rand_type;
79   long rand_deg;
80   long rand_sep;
81   long *end_ptr;
82   int debug;
83   static const int rand_max = 0x7fffffff;         // biggest signed Uint32
84
85 public:
86   RandomGenerator();
87   ~RandomGenerator();
88
89   // Documentation of user-visible calls:
90
91   // Initialize the RNG with a 31-bit seed
92   // if x is zero or absent, calls to time() will get a time-randomized seed
93   // the value returned is the value of the seed used.
94   int srand(int x=0);
95
96   // generate random 31-bit numbers
97   // calls to the following return a value evenly distributed between u (or
98   // 0 if not specified) and v (or rand_max if not specified).  Return
99   // values may include u, but never v.
100   int rand();
101   int rand(int v);
102   int rand(int u, int v);
103   double randf(double v);
104   double randf(double u, double v);
105
106   // For Squirrel wrapper, since miniswig (and even squirrel?) doesn't
107   // support function overloading or doubles
108   int rand1i(int v) { return rand(v); }
109   int rand2i(int u, int v) { return rand(u, v); }
110   float rand1f(float v)
111   { return static_cast<float>(randf(static_cast<double>(v))); }
112   float rand2f(float u, float v)
113   { return static_cast<float>(randf(static_cast<double>(u),
114                                     static_cast<double>(v))); }
115
116   //private:
117   void initialize();
118   void srandom(unsigned long x);
119   //  void srandomdev();
120   //  char *initstate(unsigned long seed, char *arg_state, long n);
121   //  char *setstate(char *arg_state);
122   long random();
123
124 private:
125   RandomGenerator(const RandomGenerator&);
126   RandomGenerator& operator=(const RandomGenerator&);
127 };
128
129 extern RandomGenerator systemRandom;
130
131 #endif //__RANDOM_GENERATOR__
132
133 /* EOF */