1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
|
|
4 | * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team |
4 | * Copyright (©) 2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * |
6 | * |
6 | * Deliantra is free software: you can redistribute it and/or modify it under |
7 | * Deliantra is free software: you can redistribute it and/or modify it under |
7 | * the terms of the Affero GNU General Public License as published by the |
8 | * the terms of the Affero GNU General Public License as published by the |
8 | * Free Software Foundation, either version 3 of the License, or (at your |
9 | * Free Software Foundation, either version 3 of the License, or (at your |
9 | * option) any later version. |
10 | * option) any later version. |
… | |
… | |
21 | */ |
22 | */ |
22 | |
23 | |
23 | #ifndef RNG_H__ |
24 | #ifndef RNG_H__ |
24 | #define RNG_H__ |
25 | #define RNG_H__ |
25 | |
26 | |
26 | #include <compiler.h> |
27 | #include "ecb.h" |
27 | |
28 | |
28 | typedef uint32_t seed_t; // overkill |
29 | typedef uint32_t seed_t; // overkill |
29 | |
30 | |
30 | // P. L'Ecuyer, “Maximally Equidistributed Combined Tausworthe Generators”, Mathematics of Computation, 65, 213 (1996), 203–213. |
31 | // P. L'Ecuyer, “Maximally Equidistributed Combined Tausworthe Generators”, Mathematics of Computation, 65, 213 (1996), 203–213. |
31 | // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps |
32 | // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps |
… | |
… | |
170 | } |
171 | } |
171 | |
172 | |
172 | // uniform distribution, [0 .. num - 1] |
173 | // uniform distribution, [0 .. num - 1] |
173 | uint32_t operator ()(uint32_t num) |
174 | uint32_t operator ()(uint32_t num) |
174 | { |
175 | { |
175 | return !is_constant (num) ? get_range (num) // non-constant |
176 | return !ecb_is_constant (num) ? get_range (num) // non-constant |
176 | : num & (num - 1) ? (this->next () * (uint64_t)num) >> 32U // constant, non-power-of-two |
177 | : num & (num - 1) ? (this->next () * (uint64_t)num) >> 32U // constant, non-power-of-two |
177 | : this->next () & (num - 1); // constant, power-of-two |
178 | : this->next () & (num - 1); // constant, power-of-two |
178 | } |
179 | } |
179 | |
180 | |
180 | // return a number within the closed interval [min .. max], max can be >, < or == min. |
181 | // return a number within the closed interval [min .. max], max can be >, < or == min. |
181 | int operator () (int r_min, int r_max) |
182 | int operator () (int r_min, int r_max) |
182 | { |
183 | { |
183 | return is_constant (r_min <= r_max) && r_min <= r_max |
184 | return ecb_is_constant (r_min <= r_max) && r_min <= r_max |
184 | ? r_min + operator ()(r_max - r_min + 1) |
185 | ? r_min + operator ()(r_max - r_min + 1) |
185 | : get_range (r_min, r_max); |
186 | : get_range (r_min, r_max); |
186 | } |
187 | } |
187 | |
188 | |
188 | uint32_t get_u32 (); |
189 | uint32_t get_u32 (); |