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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide annotations) (download)
Fri Oct 7 03:35:12 2016 UTC (8 years, 1 month 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 dashley 11 //----------------------------------------------------------------------------------------------------
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