1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#ifndef LOVE_MATH_RANDOM_GENERATOR_H
22#define LOVE_MATH_RANDOM_GENERATOR_H
23
24// LOVE
25#include "common/config.h"
26#include "common/Exception.h"
27#include "common/math.h"
28#include "common/int.h"
29#include "common/Object.h"
30
31// C++
32#include <limits>
33#include <string>
34
35namespace love
36{
37namespace math
38{
39
40class RandomGenerator : public Object
41{
42public:
43
44 static love::Type type;
45
46 union Seed
47 {
48 uint64 b64;
49 struct
50 {
51#ifdef LOVE_BIG_ENDIAN
52 uint32 high;
53 uint32 low;
54#else
55 uint32 low;
56 uint32 high;
57#endif
58 } b32;
59 };
60
61 RandomGenerator();
62 virtual ~RandomGenerator() {}
63
64 /**
65 * Return uniformly distributed pseudo random integer.
66 *
67 * @return Pseudo random integer in [0,2^64).
68 **/
69 uint64 rand();
70
71 /**
72 * Get uniformly distributed pseudo random number in [0,1).
73 *
74 * @return Pseudo random number in [0,1).
75 **/
76 inline double random()
77 {
78 uint64 r = rand();
79
80 // From http://xoroshiro.di.unimi.it
81 union { uint64 i; double d; } u;
82 u.i = ((0x3FFULL) << 52) | (r >> 12);
83
84 return u.d - 1.0;
85 }
86
87 /**
88 * Get uniformly distributed pseudo random number in [0,max).
89 *
90 * @return Pseudo random number in [0,max).
91 **/
92 inline double random(double max)
93 {
94 return random() * max;
95 }
96
97 /**
98 * Get uniformly distributed pseudo random number in [min, max).
99 *
100 * @return Pseudo random number in [min, max).
101 **/
102 inline double random(double min, double max)
103 {
104 return random() * (max - min) + min;
105 }
106
107 /**
108 * Get normally distributed pseudo random number.
109 *
110 * @param stddev Standard deviation of the distribution.
111 * @return Normally distributed random number with mean 0 and variance (stddev)².
112 **/
113 double randomNormal(double stddev);
114
115 /**
116 * Set pseudo-random seed.
117 * It's up to the implementation how to use this.
118 **/
119 void setSeed(Seed seed);
120
121 /**
122 * Get the previously set pseudo-random seed.
123 **/
124 Seed getSeed() const;
125
126 /**
127 * Set the internal implementation-dependent state value based on a string.
128 **/
129 void setState(const std::string &statestr);
130
131 /**
132 * Get a string representation of the implementation-dependent internal
133 * state value.
134 **/
135 std::string getState() const;
136
137private:
138
139 Seed seed;
140 Seed rng_state;
141 double last_randomnormal;
142
143}; // RandomGenerator
144
145} // math
146} // love
147
148#endif // LOVE_MATH_RANDOM_GENERATOR_H
149