/[dtapublic]/projs/trunk/projs/20120418_blackjacksim/source/bjcceval/random.c
ViewVC logotype

Contents of /projs/trunk/projs/20120418_blackjacksim/source/bjcceval/random.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations) (download)
Fri Oct 7 03:35:12 2016 UTC (8 years, 2 months ago) by dashley
Original Path: swprojs/trunk/projs/20120418_blackjacksim/source/bjcceval/random.c
File MIME type: text/plain
File size: 7830 byte(s)
Commit of Blackjack simulation project.
1 //----------------------------------------------------------------------------------------------------
2 //$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/dtaipubs/cron/2010/blackjack_201010/source/bjcceval/random.c,v 1.7 2012/04/15 12:57:08 dashley Exp $
3 //----------------------------------------------------------------------------------------------------
4 //Copyright (C) 2012, David T. Ashley.
5 //
6 //This file is part of BJCCEVAL, a program that evaluates by simulation
7 //the best basic strategy, card-counting, and other playing strategies
8 //for several variants of the game of Blackjack.
9 //
10 //BJCCEVAL is free software: you can redistribute it and/or modify
11 //it under the terms of the GNU General Public License as published by
12 //the Free Software Foundation, either version 3 of the License, or
13 //(at your option) any later version.
14 //
15 //BJCCEVAL is distributed in the hope that it will be useful,
16 //but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 //GNU General Public License for more details.
19 //
20 //You should have received a copy of the GNU General Public License
21 //along with this program. If not, see <http://www.gnu.org/licenses/>.
22 //(A copy of the GNU General Public License, Version 3 is provided in
23 //the file "COPYING" distributed with BJCCEVAL.)
24 //
25 //David T. Ashley can be contacted at DASHLEY@GMAIL.COM and/or at
26 //P.O. Box 918, Marshall MI 49068.
27 //----------------------------------------------------------------------------------------------------
28 #define MODULE_RANDOM
29
30 #include "mt19937.h"
31 #include "random.h"
32
33 //Returns a single random bit as FALSE or TRUE.
34 //
35 //Unit-tested 20120411. Unit-testing involved stepping
36 //through the function and observing behavior.
37 //
38 unsigned RANDOM_Bit(void)
39 {
40 static unsigned nbitsavail = 0;
41 static unsigned bit_buffer;
42 unsigned rv;
43
44 if (! nbitsavail)
45 {
46 bit_buffer = RANDOM_Uint32();
47 nbitsavail = 32;
48 }
49
50 if (bit_buffer & 0x01)
51 {
52 rv = 1;
53 }
54 else
55 {
56 rv = 0;
57 }
58
59 bit_buffer >>= 1;
60 nbitsavail--;
61
62 return(rv);
63 }
64
65
66 //Returns a random unsigned integer. Because the MT19937
67 //test vectors passed when the MT19937 code was added,
68 //this was not carefully unit-tested.
69 //
70 //However, a basic unit test involving 256 bins for modulo
71 //result and 256 bins for partition was performed. The results
72 //seemed reasonable.
73 //
74 //Unit tested 20120411.
75 //
76 unsigned RANDOM_Uint32(void)
77 {
78 unsigned rv;
79
80 rv = MT19937_genrand_int32();
81
82 return(rv);
83 }
84
85
86 //Returns a randomly-distributed value between min and max inclusive.
87 //
88 //20120411: Unit-tested. Attempted full statement coverage.
89 //
90 unsigned RANDOM_UintBounded32(unsigned min, unsigned max)
91 {
92 unsigned diff;
93 //Difference between max and min values.
94 unsigned span;
95 //Number of different values that could be returned that would satisfy the
96 //criteria of being between min and max, inclusive.
97 unsigned max_random_allowed;
98 //Max random value that would be of use to us.
99 unsigned random_val;
100 //The random value obtained.
101 unsigned rv;
102 //The value returned to the caller.
103
104 //Swap min and max if they are reversed.
105 if (min > max)
106 {
107 unsigned temp;
108
109 temp = min;
110 min = max;
111 max = temp;
112 }
113
114 //Calculate parameters that parameterize the generation.
115 diff = max - min;
116 span = diff + 1; //Possible rollover to 0, but this case excluded below.
117
118 if (diff == 0)
119 {
120 rv = min; //We can choose only one value. Choose it.
121 }
122 else if (diff == 0xFFFFFFFF)
123 {
124 rv = RANDOM_Uint32(); //The input parameters are 0 and 0xFFFFFFFF. We can't
125 //safely calculate with this max range, so return without
126 //further calculation.
127 }
128 else
129 {
130 //At this point we can possibly "fold" or "equivalence class"
131 //any random integer we obtain to meet the interval.
132 //
133 //Figure out how big of a random unsigned integer would be useful to us.
134 //
135 //The correct expression for the maximum random integer that is useful to us is
136 //
137 // 0x100000000 - (0x100000000 mod span) - 1.
138 //
139 //This isn't easy to calculate with 32-bit arithmetic.
140 //
141 // 0xFFFFFFFF - (0x100000000 mod span)
142 //
143 //Note that
144 //
145 // (0x100000000 mod span) = ((0xFFFFFFFF mod span) + 1) mod span
146 //
147 //So the overall expression is:
148 //
149 // 0xFFFFFFFF - (((0xFFFFFFFF mod span) + 1) mod span)
150 //
151 max_random_allowed = 0xFFFFFFFF - (((0xFFFFFFFF % span) + 1) % span);
152
153 do
154 {
155 random_val = RANDOM_Uint32();
156 } while (random_val > max_random_allowed);
157
158 rv = (random_val % span) + min;
159 }
160
161 return(rv);
162 }
163
164
165 //Returns a uniformly distributed signed integer.
166 //
167 //20120414: Unit tested to be sure it attains test cases commented out below.
168 //
169 int RANDOM_Int32(void)
170 {
171 unsigned ov;
172 int rv;
173
174 //Because the distribution of an unsigned is uniform (no previous
175 //value gives information about the next value) it should be
176 //acceptable just to let an unsigned int be remapped as an int.
177 ov = RANDOM_Uint32();
178 rv = ov - 0x80000000;
179
180 //Debugging trap to be sure values map correctly from unsigned to signed.
181 //
182 //if ( (ov == 0x00000000) || (ov == 0x00000001) || (ov == 0x7FFFFFFF) || (ov == 0x80000000)
183 // || (ov == 0x80000001) || (ov == 0xFFFFFFFE) || (ov == 0xFFFFFFFF))
184 // {
185 // static unsigned count=0;
186 //
187 // count++;
188 //
189 // printf("----------\n");
190 // printf("Result #%u\n", count);
191 // printf("ov: %u rv: %d\n", ov, rv);
192 // printf("ov: %08X rv: %08X\n", ov, rv);
193 // }
194
195 return(rv);
196 }
197
198
199 //Returns a random signed integer in the interval [min, max].
200 //
201 //20120415: Several intervals checked. Function seems OK, including intervals
202 //at negative and positive limits.
203 //
204 int RANDOM_IntBounded32(int min, int max)
205 {
206 long long bigmin, bigmax, bigdiff;
207 long long int ri;
208
209 if (min > max)
210 {
211 int temp;
212
213 temp = min;
214 min = max;
215 max = temp;
216 }
217
218 bigmin = min;
219 bigmax = max;
220 bigdiff = bigmax - bigmin;
221
222 ri = RANDOM_UintBounded32(0, (unsigned)bigdiff);
223
224 ri += bigmin;
225
226 return((int)ri);
227 }
228
229
230 //Returns version control information for the .C file.
231 //
232 const char *RANDOM_Vcinfo_C(void)
233 {
234 return("$Revision: 1.7 $");
235 }
236
237
238 //Returns version control for the .H file.
239 //
240 const char *RANDOM_Vcinfo_H(void)
241 {
242 return(RANDOM_VCINFO_H);
243 }
244
245
246
247 #if defined(P_TEST) || defined(P_TEST_RANDOM)
248
249 int RANDOM_Test(void)
250 {
251 return(1);
252 }
253
254 #endif
255
256 //----------------------------------------------------------------------------------------------------
257 //$Log: random.c,v $
258 //Revision 1.7 2012/04/15 12:57:08 dashley
259 //Unit testing performed.
260 //
261 //Revision 1.6 2012/04/12 01:51:57 dashley
262 //Edits.
263 //
264 //Revision 1.5 2012/04/11 03:31:51 dashley
265 //Edits.
266 //
267 //Revision 1.4 2012/03/30 00:20:14 dashley
268 //Edits.
269 //
270 //Revision 1.3 2012/03/29 23:44:01 dashley
271 //Edits.
272 //
273 //Revision 1.2 2012/03/15 23:38:08 dashley
274 //License text enhanced.
275 //
276 //Revision 1.1 2012/03/11 21:01:46 dashley
277 //Initial checkin.
278 //----------------------------------------------------------------------------------------------------
279 //End of $RCSfile: random.c,v $
280 //----------------------------------------------------------------------------------------------------

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25