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 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. |
10 | * |
11 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * GNU General Public License for more details. |
15 | * |
16 | * |
16 | * You should have received a copy of the Affero GNU General Public License |
17 | * You should have received a copy of the Affero GNU General Public License |
17 | * and the GNU General Public License along with this program. If not, see |
18 | * and the GNU General Public License along with this program. If not, see |
18 | * <http://www.gnu.org/licenses/>. |
19 | * <http://www.gnu.org/licenses/>. |
19 | * |
20 | * |
20 | * The authors can be reached via e-mail to <support@deliantra.net> |
21 | * The authors can be reached via e-mail to <support@deliantra.net> |
21 | */ |
22 | */ |
22 | |
23 | |
23 | #ifndef RNG_H__ |
24 | #ifndef RNG_H__ |
24 | #define RNG_H__ |
25 | #define RNG_H__ |
… | |
… | |
77 | x = x * A + B; |
78 | x = x * A + B; |
78 | return x; |
79 | return x; |
79 | } |
80 | } |
80 | }; |
81 | }; |
81 | |
82 | |
82 | typedef lc_rng<3039177861U, 0U> borosh_niederreiter_rng; |
83 | typedef lc_rng<3039177861U, 0U> borosh_niederreiter_rng; |
83 | typedef lc_rng<2147001325U, 715136305U> bcpl_rng; |
84 | typedef lc_rng<2147001325U, 715136305U> bcpl_rng; |
84 | typedef lc_rng< 1664525U, 1U> lavaux_janssens_rng; |
85 | typedef lc_rng< 1664525U, 1U> lavaux_janssens_rng; |
|
|
86 | typedef lc_rng< 1664525U, 1013904223U> numerical_recipes_rng; |
85 | |
87 | |
86 | template<typename T, int N, int k> |
88 | template<typename T, int N, int k> |
87 | struct gfsr_rng |
89 | struct gfsr_rng |
88 | { |
90 | { |
89 | int i; |
91 | int i; |
… | |
… | |
137 | // and likely of higher quality. |
139 | // and likely of higher quality. |
138 | typedef gfsr_rng<uint32_t, 250, 103> r250_rng; |
140 | typedef gfsr_rng<uint32_t, 250, 103> r250_rng; |
139 | typedef gfsr_rng<uint32_t, 521, 168> r521_rng; |
141 | typedef gfsr_rng<uint32_t, 521, 168> r521_rng; |
140 | |
142 | |
141 | // freeciv uses this one, so it's good enough for us :) |
143 | // freeciv uses this one, so it's good enough for us :) |
142 | // (also known as mitchell moore generator |
144 | // (also known as mitchell moore generator) |
143 | typedef gfsr_rng<uint32_t, 55, 24> freeciv_rng; |
145 | typedef gfsr_rng<uint32_t, 55, 24> freeciv_rng; |
144 | |
146 | |
145 | // this one should be high quality, but is slightly slower than tausworthe |
147 | // this one should be high quality, but is slightly slower than tausworthe |
146 | struct r250521_rng |
148 | struct r250521_rng |
147 | { |
149 | { |
… | |
… | |
169 | } |
171 | } |
170 | |
172 | |
171 | // uniform distribution, [0 .. num - 1] |
173 | // uniform distribution, [0 .. num - 1] |
172 | uint32_t operator ()(uint32_t num) |
174 | uint32_t operator ()(uint32_t num) |
173 | { |
175 | { |
174 | return !is_constant (num) ? get_range (num) // non-constant |
176 | return !ecb_is_constant (num) ? get_range (num) // non-constant |
175 | : 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 |
176 | : this->next () & (num - 1); // constant, power-of-two |
178 | : this->next () & (num - 1); // constant, power-of-two |
177 | } |
179 | } |
178 | |
180 | |
179 | // 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. |
180 | int operator () (int r_min, int r_max) |
182 | int operator () (int r_min, int r_max) |
181 | { |
183 | { |
182 | return is_constant (r_min <= r_max) && r_min <= r_max |
184 | return ecb_is_constant (r_min <= r_max) && r_min <= r_max |
183 | ? r_min + operator ()(r_max - r_min + 1) |
185 | ? r_min + operator ()(r_max - r_min + 1) |
184 | : get_range (r_min, r_max); |
186 | : get_range (r_min, r_max); |
185 | } |
187 | } |
186 | |
188 | |
187 | uint32_t get_u32 (); |
189 | uint32_t get_u32 (); |