Rev 154 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 154 | Rev 169 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
5 | Copyright (C) 2015- |
5 | Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad |
6 | 6 | ||
7 | Stockfish is free software: you can redistribute it and/or modify |
7 | Stockfish is free software: you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation, either version 3 of the License, or |
9 | the Free Software Foundation, either version 3 of the License, or |
10 | (at your option) any later version. |
10 | (at your option) any later version. |
Line 23... | Line 23... | ||
23 | #include "bitboard.h" |
23 | #include "bitboard.h" |
24 | #include "misc.h" |
24 | #include "misc.h" |
25 | 25 | ||
26 | uint8_t PopCnt16[1 << 16]; |
26 | uint8_t PopCnt16[1 << 16]; |
27 | int SquareDistance[SQUARE_NB][SQUARE_NB]; |
27 | int SquareDistance[SQUARE_NB][SQUARE_NB]; |
28 | - | ||
29 | Bitboard RookMasks [SQUARE_NB]; |
- | |
30 | Bitboard RookMagics [SQUARE_NB]; |
- | |
31 | Bitboard* RookAttacks[SQUARE_NB]; |
- | |
32 | unsigned RookShifts [SQUARE_NB]; |
- | |
33 | - | ||
34 | Bitboard BishopMasks [SQUARE_NB]; |
- | |
35 | Bitboard BishopMagics [SQUARE_NB]; |
- | |
36 | Bitboard* BishopAttacks[SQUARE_NB]; |
- | |
37 | unsigned BishopShifts [SQUARE_NB]; |
- | |
38 | 28 | ||
39 | Bitboard SquareBB[SQUARE_NB]; |
29 | Bitboard SquareBB[SQUARE_NB]; |
40 | Bitboard FileBB[FILE_NB]; |
30 | Bitboard FileBB[FILE_NB]; |
41 | Bitboard RankBB[RANK_NB]; |
31 | Bitboard RankBB[RANK_NB]; |
42 | Bitboard AdjacentFilesBB[FILE_NB]; |
32 | Bitboard AdjacentFilesBB[FILE_NB]; |
43 | Bitboard |
33 | Bitboard ForwardRanksBB[COLOR_NB][RANK_NB]; |
44 | Bitboard StepAttacksBB[PIECE_NB][SQUARE_NB]; |
- | |
45 | Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; |
34 | Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; |
46 | Bitboard LineBB[SQUARE_NB][SQUARE_NB]; |
35 | Bitboard LineBB[SQUARE_NB][SQUARE_NB]; |
47 | Bitboard DistanceRingBB[SQUARE_NB][8]; |
36 | Bitboard DistanceRingBB[SQUARE_NB][8]; |
48 | Bitboard |
37 | Bitboard ForwardFileBB[COLOR_NB][SQUARE_NB]; |
49 | Bitboard PassedPawnMask[COLOR_NB][SQUARE_NB]; |
38 | Bitboard PassedPawnMask[COLOR_NB][SQUARE_NB]; |
50 | Bitboard PawnAttackSpan[COLOR_NB][SQUARE_NB]; |
39 | Bitboard PawnAttackSpan[COLOR_NB][SQUARE_NB]; |
51 | Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; |
40 | Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; |
- | 41 | Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; |
|
- | 42 | ||
- | 43 | Magic RookMagics[SQUARE_NB]; |
|
- | 44 | Magic BishopMagics[SQUARE_NB]; |
|
52 | 45 | ||
53 | namespace { |
46 | namespace { |
54 | 47 | ||
55 | // De Bruijn sequences. See chessprogramming.wikispaces.com/BitScan |
48 | // De Bruijn sequences. See chessprogramming.wikispaces.com/BitScan |
56 | const uint64_t DeBruijn64 = 0x3F79D71B4CB0A89ULL; |
49 | const uint64_t DeBruijn64 = 0x3F79D71B4CB0A89ULL; |
Line 59... | Line 52... | ||
59 | int MSBTable[256]; // To implement software msb() |
52 | int MSBTable[256]; // To implement software msb() |
60 | Square BSFTable[SQUARE_NB]; // To implement software bitscan |
53 | Square BSFTable[SQUARE_NB]; // To implement software bitscan |
61 | Bitboard RookTable[0x19000]; // To store rook attacks |
54 | Bitboard RookTable[0x19000]; // To store rook attacks |
62 | Bitboard BishopTable[0x1480]; // To store bishop attacks |
55 | Bitboard BishopTable[0x1480]; // To store bishop attacks |
63 | 56 | ||
64 | typedef unsigned (Fn)(Square, Bitboard); |
- | |
65 | - | ||
66 | void init_magics(Bitboard table[], |
57 | void init_magics(Bitboard table[], Magic magics[], Direction directions[]); |
67 | Bitboard masks[], unsigned shifts[], Square deltas[], Fn index); |
- | |
68 | 58 | ||
69 | // bsf_index() returns the index into BSFTable[] to look up the bitscan. Uses |
59 | // bsf_index() returns the index into BSFTable[] to look up the bitscan. Uses |
70 | // Matt Taylor's folding for 32 bit case, extended to 64 bit by Kim Walisch. |
60 | // Matt Taylor's folding for 32 bit case, extended to 64 bit by Kim Walisch. |
71 | 61 | ||
72 | unsigned bsf_index(Bitboard b) { |
62 | unsigned bsf_index(Bitboard b) { |
Line 171... | Line 161... | ||
171 | 161 | ||
172 | for (File f = FILE_A; f <= FILE_H; ++f) |
162 | for (File f = FILE_A; f <= FILE_H; ++f) |
173 | AdjacentFilesBB[f] = (f > FILE_A ? FileBB[f - 1] : 0) | (f < FILE_H ? FileBB[f + 1] : 0); |
163 | AdjacentFilesBB[f] = (f > FILE_A ? FileBB[f - 1] : 0) | (f < FILE_H ? FileBB[f + 1] : 0); |
174 | 164 | ||
175 | for (Rank r = RANK_1; r < RANK_8; ++r) |
165 | for (Rank r = RANK_1; r < RANK_8; ++r) |
176 |
|
166 | ForwardRanksBB[WHITE][r] = ~(ForwardRanksBB[BLACK][r + 1] = ForwardRanksBB[BLACK][r] | RankBB[r]); |
177 | 167 | ||
178 | for (Color c = WHITE; c <= BLACK; ++c) |
168 | for (Color c = WHITE; c <= BLACK; ++c) |
179 | for (Square s = SQ_A1; s <= SQ_H8; ++s) |
169 | for (Square s = SQ_A1; s <= SQ_H8; ++s) |
180 | { |
170 | { |
181 |
|
171 | ForwardFileBB [c][s] = ForwardRanksBB[c][rank_of(s)] & FileBB[file_of(s)]; |
182 | PawnAttackSpan[c][s] = |
172 | PawnAttackSpan[c][s] = ForwardRanksBB[c][rank_of(s)] & AdjacentFilesBB[file_of(s)]; |
183 | PassedPawnMask[c][s] = |
173 | PassedPawnMask[c][s] = ForwardFileBB [c][s] | PawnAttackSpan[c][s]; |
184 | } |
174 | } |
185 | 175 | ||
186 | for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) |
176 | for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) |
187 | for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) |
177 | for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) |
188 | if (s1 != s2) |
178 | if (s1 != s2) |
189 | { |
179 | { |
190 | SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2)); |
180 | SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2)); |
191 | DistanceRingBB[s1][SquareDistance[s1][s2] - 1] |= s2; |
181 | DistanceRingBB[s1][SquareDistance[s1][s2] - 1] |= s2; |
192 | } |
182 | } |
193 | 183 | ||
194 | int steps[][ |
184 | int steps[][5] = { {}, { 7, 9 }, { 6, 10, 15, 17 }, {}, {}, {}, { 1, 7, 8, 9 } }; |
195 | {}, {}, {}, { 9, 7, -7, -9, 8, 1, -1, -8 } }; |
- | |
196 | 185 | ||
197 | for (Color c = WHITE; c <= BLACK; ++c) |
186 | for (Color c = WHITE; c <= BLACK; ++c) |
198 | for (PieceType pt |
187 | for (PieceType pt : { PAWN, KNIGHT, KING }) |
199 | for (Square s = SQ_A1; s <= SQ_H8; ++s) |
188 | for (Square s = SQ_A1; s <= SQ_H8; ++s) |
200 | for (int i = 0; steps[pt][i]; ++i) |
189 | for (int i = 0; steps[pt][i]; ++i) |
201 | { |
190 | { |
202 | Square to = s + |
191 | Square to = s + Direction(c == WHITE ? steps[pt][i] : -steps[pt][i]); |
203 | 192 | ||
204 | if (is_ok(to) && distance(s, to) < 3) |
193 | if (is_ok(to) && distance(s, to) < 3) |
- | 194 | { |
|
- | 195 | if (pt == PAWN) |
|
- | 196 | PawnAttacks[c][s] |= to; |
|
- | 197 | else |
|
205 |
|
198 | PseudoAttacks[pt][s] |= to; |
- | 199 | } |
|
206 | } |
200 | } |
207 | 201 | ||
208 |
|
202 | Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST }; |
209 |
|
203 | Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }; |
210 | 204 | ||
211 | init_magics(RookTable, |
205 | init_magics(RookTable, RookMagics, RookDirections); |
212 | init_magics(BishopTable, |
206 | init_magics(BishopTable, BishopMagics, BishopDirections); |
213 | 207 | ||
214 | for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) |
208 | for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) |
215 | { |
209 | { |
216 | PseudoAttacks[QUEEN][s1] = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0); |
210 | PseudoAttacks[QUEEN][s1] = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0); |
217 | PseudoAttacks[QUEEN][s1] |= PseudoAttacks[ ROOK][s1] = attacks_bb< ROOK>(s1, 0); |
211 | PseudoAttacks[QUEEN][s1] |= PseudoAttacks[ ROOK][s1] = attacks_bb< ROOK>(s1, 0); |
218 | 212 | ||
219 | for ( |
213 | for (PieceType pt : { BISHOP, ROOK }) |
220 | for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) |
214 | for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) |
221 | { |
215 | { |
222 | if (!(PseudoAttacks[ |
216 | if (!(PseudoAttacks[pt][s1] & s2)) |
223 | continue; |
217 | continue; |
224 | 218 | ||
225 | LineBB[s1][s2] = (attacks_bb( |
219 | LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2; |
226 | BetweenBB[s1][s2] = attacks_bb( |
220 | BetweenBB[s1][s2] = attacks_bb(pt, s1, SquareBB[s2]) & attacks_bb(pt, s2, SquareBB[s1]); |
227 | } |
221 | } |
228 | } |
222 | } |
229 | } |
223 | } |
230 | 224 | ||
231 | 225 | ||
232 | namespace { |
226 | namespace { |
233 | 227 | ||
234 | Bitboard sliding_attack( |
228 | Bitboard sliding_attack(Direction directions[], Square sq, Bitboard occupied) { |
235 | 229 | ||
236 | Bitboard attack = 0; |
230 | Bitboard attack = 0; |
237 | 231 | ||
238 | for (int i = 0; i < 4; ++i) |
232 | for (int i = 0; i < 4; ++i) |
239 | for (Square s = sq + |
233 | for (Square s = sq + directions[i]; |
240 | is_ok(s) && distance(s, s - |
234 | is_ok(s) && distance(s, s - directions[i]) == 1; |
241 | s += |
235 | s += directions[i]) |
242 | { |
236 | { |
243 | attack |= s; |
237 | attack |= s; |
244 | 238 | ||
245 | if (occupied & s) |
239 | if (occupied & s) |
246 | break; |
240 | break; |
Line 253... | Line 247... | ||
253 | // init_magics() computes all rook and bishop attacks at startup. Magic |
247 | // init_magics() computes all rook and bishop attacks at startup. Magic |
254 | // bitboards are used to look up attacks of sliding pieces. As a reference see |
248 | // bitboards are used to look up attacks of sliding pieces. As a reference see |
255 | // chessprogramming.wikispaces.com/Magic+Bitboards. In particular, here we |
249 | // chessprogramming.wikispaces.com/Magic+Bitboards. In particular, here we |
256 | // use the so called "fancy" approach. |
250 | // use the so called "fancy" approach. |
257 | 251 | ||
258 | void init_magics(Bitboard table[], |
252 | void init_magics(Bitboard table[], Magic magics[], Direction directions[]) { |
259 | Bitboard masks[], unsigned shifts[], Square deltas[], Fn index) { |
- | |
260 | 253 | ||
- | 254 | // Optimal PRNG seeds to pick the correct magics in the shortest time |
|
261 | int seeds[][RANK_NB] = { { 8977, 44560, 54343, 38998, 5731, 95205, 104912, 17020 }, |
255 | int seeds[][RANK_NB] = { { 8977, 44560, 54343, 38998, 5731, 95205, 104912, 17020 }, |
262 | { 728, 10316, 55013, 32803, 12281, 15100, 16645, 255 } }; |
256 | { 728, 10316, 55013, 32803, 12281, 15100, 16645, 255 } }; |
263 | 257 | ||
264 | Bitboard occupancy[4096], reference[4096], edges, b; |
258 | Bitboard occupancy[4096], reference[4096], edges, b; |
265 | int |
259 | int epoch[4096] = {}, cnt = 0, size = 0; |
266 | - | ||
267 | // attacks[s] is a pointer to the beginning of the attacks table for square 's' |
- | |
268 | attacks[SQ_A1] = table; |
- | |
269 | 260 | ||
270 | for (Square s = SQ_A1; s <= SQ_H8; ++s) |
261 | for (Square s = SQ_A1; s <= SQ_H8; ++s) |
271 | { |
262 | { |
272 | // Board edges are not considered in the relevant occupancies |
263 | // Board edges are not considered in the relevant occupancies |
273 | edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s)); |
264 | edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s)); |
Line 275... | Line 266... | ||
275 | // Given a square 's', the mask is the bitboard of sliding attacks from |
266 | // Given a square 's', the mask is the bitboard of sliding attacks from |
276 | // 's' computed on an empty board. The index must be big enough to contain |
267 | // 's' computed on an empty board. The index must be big enough to contain |
277 | // all the attacks for each possible subset of the mask and so is 2 power |
268 | // all the attacks for each possible subset of the mask and so is 2 power |
278 | // the number of 1s of the mask. Hence we deduce the size of the shift to |
269 | // the number of 1s of the mask. Hence we deduce the size of the shift to |
279 | // apply to the 64 or 32 bits word to get the index. |
270 | // apply to the 64 or 32 bits word to get the index. |
- | 271 | Magic& m = magics[s]; |
|
280 |
|
272 | m.mask = sliding_attack(directions, s, 0) & ~edges; |
281 |
|
273 | m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask); |
- | 274 | ||
- | 275 | // Set the offset for the attacks table of the square. We have individual |
|
- | 276 | // table sizes for each square with "Fancy Magic Bitboards". |
|
- | 277 | m.attacks = s == SQ_A1 ? table : magics[s - 1].attacks + size; |
|
282 | 278 | ||
283 | // Use Carry-Rippler trick to enumerate all subsets of masks[s] and |
279 | // Use Carry-Rippler trick to enumerate all subsets of masks[s] and |
284 | // store the corresponding sliding attack bitboard in reference[]. |
280 | // store the corresponding sliding attack bitboard in reference[]. |
285 | b = size = 0; |
281 | b = size = 0; |
286 | do { |
282 | do { |
287 | occupancy[size] = b; |
283 | occupancy[size] = b; |
288 | reference[size] = sliding_attack( |
284 | reference[size] = sliding_attack(directions, s, b); |
289 | 285 | ||
290 | if (HasPext) |
286 | if (HasPext) |
291 | attacks |
287 | m.attacks[pext(b, m.mask)] = reference[size]; |
292 | 288 | ||
293 | size++; |
289 | size++; |
294 | b = (b - |
290 | b = (b - m.mask) & m.mask; |
295 | } while (b); |
291 | } while (b); |
296 | - | ||
297 | // Set the offset for the table of the next square. We have individual |
- | |
298 | // table sizes for each square with "Fancy Magic Bitboards". |
- | |
299 | if (s < SQ_H8) |
- | |
300 | attacks[s + 1] = attacks[s] + size; |
- | |
301 | 292 | ||
302 | if (HasPext) |
293 | if (HasPext) |
303 | continue; |
294 | continue; |
304 | 295 | ||
305 | PRNG rng(seeds[Is64Bit][rank_of(s)]); |
296 | PRNG rng(seeds[Is64Bit][rank_of(s)]); |
306 | 297 | ||
307 | // Find a magic for square 's' picking up an (almost) random number |
298 | // Find a magic for square 's' picking up an (almost) random number |
308 | // until we find the one that passes the verification test. |
299 | // until we find the one that passes the verification test. |
309 |
|
300 | for (int i = 0; i < size; ) |
310 |
|
301 | { |
311 |
|
302 | for (m.magic = 0; popcount((m.magic * m.mask) >> 56) < 6; ) |
312 |
|
303 | m.magic = rng.sparse_rand<Bitboard>(); |
313 | 304 | ||
314 | // A good magic must map every possible occupancy to an index that |
305 | // A good magic must map every possible occupancy to an index that |
315 | // looks up the correct sliding attack in the attacks[s] database. |
306 | // looks up the correct sliding attack in the attacks[s] database. |
316 | // Note that we build up the database for square 's' as a side |
307 | // Note that we build up the database for square 's' as a side |
317 | // effect of verifying the magic. |
308 | // effect of verifying the magic. Keep track of the attempt count |
- | 309 | // and save it in epoch[], little speed-up trick to avoid resetting |
|
- | 310 | // m.attacks[] after every failed attempt. |
|
318 | for (++ |
311 | for (++cnt, i = 0; i < size; ++i) |
319 | { |
312 | { |
320 | unsigned idx = index( |
313 | unsigned idx = m.index(occupancy[i]); |
321 | 314 | ||
322 | if ( |
315 | if (epoch[idx] < cnt) |
323 | { |
316 | { |
324 |
|
317 | epoch[idx] = cnt; |
325 | attacks |
318 | m.attacks[idx] = reference[i]; |
326 | } |
319 | } |
327 | else if (attacks |
320 | else if (m.attacks[idx] != reference[i]) |
328 | break; |
321 | break; |
329 | } |
322 | } |
330 | } |
323 | } |
331 | } |
324 | } |
332 | } |
325 | } |
333 | } |
326 | } |