Force iteration to start at 1 in analyze mode
[bonanza.git] / rand.c
1 #include "shogi.h"
2
3 /* PRNG based on Mersenne Twister (M. Matsumoto and T. Nishimura, 1998). */
4 #define RAND_M 397
5 #define MASK_U 0x80000000U
6 #define MASK_L 0x7fffffffU
7 #define MASK32 0xffffffffU
8
9 void
10 ini_rand( unsigned int u )
11 {
12   int i;
13
14   rand_work.count   = RAND_N;
15   rand_work.cnst[0] = 0;
16   rand_work.cnst[1] = 0x9908b0dfU;
17
18   u &= MASK32;
19   rand_work.vec[0] = u;
20   for ( i = 1; i < RAND_N; i++ ) 
21     {
22       u  = i + 1812433253U * ( u ^ ( u >> 30 ) );
23       u &= MASK32;
24       rand_work.vec[i] = u;
25     }
26 }
27
28
29 unsigned int
30 rand32( void )
31 {
32   unsigned int u, u0, u1, u2;
33   int i;
34
35   if ( rand_work.count == RAND_N )
36     {
37       rand_work.count = 0;
38
39       for ( i = 0; i < RAND_N-RAND_M; i++ )
40         {
41           u  = rand_work.vec[i]   & MASK_U;
42           u |= rand_work.vec[i+1] & MASK_L;
43           
44           u0 = rand_work.vec[ i + RAND_M ];
45           u1 = u >> 1;
46           u2 = rand_work.cnst[ u & 1 ];
47
48           rand_work.vec[i] = u0 ^ u1 ^ u2;
49         }
50           
51       for ( ; i < RAND_N-1 ;i++ )
52         {
53           u  = rand_work.vec[i]   & MASK_U;
54           u |= rand_work.vec[i+1] & MASK_L;
55
56           u0 = rand_work.vec[ i + RAND_M - RAND_N ];
57           u1 = u >> 1;
58           u2 = rand_work.cnst[ u & 1 ];
59
60           rand_work.vec[i] = u0 ^ u1 ^ u2;
61         }
62
63       u  = rand_work.vec[RAND_N-1] & MASK_U;
64       u |= rand_work.vec[0]        & MASK_L;
65
66       u0 = rand_work.vec[ RAND_M - 1 ];
67       u1 = u >> 1;
68       u2 = rand_work.cnst[ u & 1 ];
69
70       rand_work.vec[RAND_N-1] = u0 ^ u1 ^ u2;
71     }
72   
73   u  = rand_work.vec[ rand_work.count++ ];
74   u ^= ( u >> 11 );
75   u ^= ( u <<  7 ) & 0x9d2c5680U;
76   u ^= ( u << 15 ) & 0xefc60000U;
77   u ^= ( u >> 18 );
78
79   return u;
80 }
81
82
83 uint64_t
84 rand64( void )
85 {
86   uint64_t h = rand32();
87   uint64_t l = rand32();
88
89   return l | ( h << 32 );
90 }