ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/rng.C
Revision: 1.8
Committed: Sat Nov 17 23:33:17 2018 UTC (5 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.7: +6 -6 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*
2     * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 root 1.5 *
4 root 1.6 * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.5 *
6 root 1.1 * 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     * Free Software Foundation, either version 3 of the License, or (at your
9     * option) any later version.
10 root 1.5 *
11 root 1.1 * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15 root 1.5 *
16 root 1.1 * 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     * <http://www.gnu.org/licenses/>.
19 root 1.5 *
20 root 1.1 * The authors can be reached via e-mail to <support@deliantra.net>
21     */
22    
23 root 1.2 #include <cmath>
24    
25 root 1.1 #include <global.h>
26    
27     rand_gen rndm, rmg_rndm;
28    
29 root 1.8 ecb_noinline void
30 root 1.2 tausworthe_rng::seed (uint32_t seed)
31 root 1.1 {
32     state [0] = seed * 69069U; if (state [0] < 2U) state [0] += 2U;
33     state [1] = state [0] * 69069U; if (state [1] < 8U) state [1] += 8U;
34     state [2] = state [1] * 69069U; if (state [2] < 16U) state [2] += 16U;
35     state [3] = state [2] * 69069U; if (state [3] < 128U) state [3] += 128U;
36    
37     for (int i = 11; --i; )
38     next ();
39     }
40    
41     uint32_t
42 root 1.2 tausworthe_rng::next ()
43 root 1.1 {
44     state [0] = ((state [0] & 0xFFFFFFFEU) << 18U) ^ (((state [0] << 6U) ^ state [0]) >> 13U);
45     state [1] = ((state [1] & 0xFFFFFFF8U) << 2U) ^ (((state [1] << 2U) ^ state [1]) >> 27U);
46     state [2] = ((state [2] & 0xFFFFFFF0U) << 7U) ^ (((state [2] << 13U) ^ state [2]) >> 21U);
47     state [3] = ((state [3] & 0xFFFFFF80U) << 13U) ^ (((state [3] << 3U) ^ state [3]) >> 12U);
48    
49     return state [0] ^ state [1] ^ state [2] ^ state [3];
50     }
51    
52 root 1.8 ecb_noinline void
53 root 1.2 r250521_rng::seed (uint32_t seed)
54 root 1.1 {
55 root 1.2 xorshift_rng rng;
56 root 1.1
57     rng.seed (seed);
58    
59     r250.seed_rng (rng);
60     r521.seed_rng (rng);
61     }
62    
63     uint32_t
64 root 1.2 r250521_rng::next ()
65 root 1.1 {
66     return r250.next () ^ r521.next ();
67     }
68    
69     template<class generator>
70     uint32_t
71     random_number_generator<generator>::get_range (uint32_t num)
72     {
73     return (this->next () * (uint64_t)num) >> 32U;
74     }
75    
76     template<class generator>
77 root 1.8 ecb_noinline uint32_t
78 root 1.1 random_number_generator<generator>::get_u32 ()
79     {
80     return generator::next ();
81     }
82    
83     template<class generator>
84 root 1.8 ecb_noinline uint64_t
85 root 1.1 random_number_generator<generator>::get_u64 ()
86     {
87     return (uint64_t (get_u32 ()) << 32U) | get_u32 ();
88     }
89    
90 root 1.2 template<class generator>
91 root 1.8 ecb_noinline float
92 root 1.2 random_number_generator<generator>::get_float ()
93     {
94     return this->next () / (float)0x100000000ULL;
95     }
96    
97     template<class generator>
98 root 1.8 ecb_noinline double
99 root 1.2 random_number_generator<generator>::get_double ()
100     {
101     return this->next () / (double)0x100000000ULL;
102     }
103    
104 root 1.1 // return a number within (min .. max)
105     template<class generator>
106 root 1.7 int
107 root 1.1 random_number_generator<generator>::get_range (int r_min, int r_max)
108     {
109     return r_min + get_range (max (r_max - r_min + 1, 0));
110     }
111    
112 root 1.2 template<class generator>
113     uint32_t
114     random_number_generator<generator>::poisson (double mean)
115     {
116     double g = std::exp (-mean);
117     uint32_t em = 0;
118    
119     double t = get_double ();
120    
121     while (t > g)
122     {
123     ++em;
124     t *= get_double ();
125     }
126    
127     return em;
128     }
129    
130     template struct random_number_generator<bcpl_rng>;
131     template struct random_number_generator<borosh_niederreiter_rng>;
132     template struct random_number_generator<tausworthe_rng>;
133     template struct random_number_generator<xorshift_rng>;
134     template struct random_number_generator<freeciv_rng>;
135     template struct random_number_generator<r250_rng>;
136     template struct random_number_generator<r521_rng>;
137     template struct random_number_generator<r250521_rng>;
138 root 1.1