forked from hoshir/zebra
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bitboard.c
145 lines (111 loc) · 3.21 KB
/
bitboard.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
File: bitboard.c
Created: November 21, 1999
Modified: November 24, 2005
Authors: Gunnar Andersson ([email protected])
Toshihiko Okuhara
Contents: Basic bitboard manipulations
*/
#include "bitboard.h"
#include "constant.h"
#include "macros.h"
BitBoard square_mask[100];
/*
NON_ITERATIVE_POPCOUNT
Counts the number of bits set in a 64-bit integer.
This is done using some bitfiddling tricks.
*/
INLINE unsigned int REGPARM(2)
non_iterative_popcount( unsigned int n1, unsigned int n2 ) {
n1 = n1 - ((n1 >> 1) & 0x55555555u);
n2 = n2 - ((n2 >> 1) & 0x55555555u);
n1 = (n1 & 0x33333333u) + ((n1 >> 2) & 0x33333333u);
n2 = (n2 & 0x33333333u) + ((n2 >> 2) & 0x33333333u);
n1 = (n1 + (n1 >> 4)) & 0x0F0F0F0Fu;
n2 = (n2 + (n2 >> 4)) & 0x0F0F0F0Fu;
return ((n1 + n2) * 0x01010101u) >> 24;
}
/*
ITERATIVE_POPCOUNT
Counts the number of bits set in a 64-bit integer.
This is done using an iterative procedure which loops
a number of times equal to the number of bits set,
hence this function is fast when the number of bits
set is low.
*/
INLINE unsigned int REGPARM(2)
iterative_popcount( unsigned int n1, unsigned int n2 ) {
unsigned int n;
n = 0;
for ( ; n1 != 0; n++, n1 &= (n1 - 1) )
;
for ( ; n2 != 0; n++, n2 &= (n2 - 1) )
;
return n;
}
/*
BIT_REVERSE_32
Returns the bit-reverse of a 32-bit integer.
*/
unsigned int REGPARM(1)
bit_reverse_32( unsigned int val ) {
val = ((val >> 1) & 0x55555555) | ((val << 1) & 0xAAAAAAAA);
val = ((val >> 2) & 0x33333333) | ((val << 2) & 0xCCCCCCCC);
val = ((val >> 4) & 0x0F0F0F0F) | ((val << 4) & 0xF0F0F0F0);
val = ((val >> 8) & 0x00FF00FF) | ((val << 8) & 0xFF00FF00);
val = ((val >> 16) & 0x0000FFFF) | ((val << 16) & 0xFFFF0000);
return val;
}
/*
SET_BITBOARDS
Converts the vector board representation to the bitboard representation.
*/
void
set_bitboards( int *board, int side_to_move,
BitBoard *my_out, BitBoard *opp_out ) {
int i, j;
int pos;
unsigned int mask;
BitBoard my_bits, opp_bits;
my_bits.high = 0;
my_bits.low = 0;
opp_bits.high = 0;
opp_bits.low = 0;
mask = 1;
for ( i = 1; i <= 4; i++ )
for ( j = 1; j <= 8; j++, mask <<= 1 ) {
pos = 10 * i + j;
if ( board[pos] == side_to_move )
my_bits.low |= mask;
else if ( board[pos] == OPP( side_to_move ) )
opp_bits.low |= mask;
}
mask = 1;
for ( i = 5; i <= 8; i++ )
for ( j = 1; j <= 8; j++, mask <<= 1 ) {
pos = 10 * i + j;
if ( board[pos] == side_to_move )
my_bits.high |= mask;
else if ( board[pos] == OPP( side_to_move ) )
opp_bits.high |= mask;
}
*my_out = my_bits;
*opp_out = opp_bits;
}
void
init_bitboard( void ) {
int i, j;
for ( i = 1; i <= 8; i++ )
for ( j = 1; j <= 8; j++ ) {
int pos = 10 * i + j;
unsigned shift = 8 * (i - 1) + (j - 1);
if ( shift < 32 ) {
square_mask[pos].low = 1ul << shift;
square_mask[pos].high = 0;
}
else {
square_mask[pos].low = 0;
square_mask[pos].high = 1ul << (shift - 32);
}
}
}