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 37... | Line 37... | ||
37 | void init(); |
37 | void init(); |
38 | const std::string pretty(Bitboard b); |
38 | const std::string pretty(Bitboard b); |
39 | 39 | ||
40 | } |
40 | } |
41 | 41 | ||
- | 42 | const Bitboard AllSquares = ~Bitboard(0); |
|
42 | const Bitboard DarkSquares = 0xAA55AA55AA55AA55ULL; |
43 | const Bitboard DarkSquares = 0xAA55AA55AA55AA55ULL; |
43 | 44 | ||
44 | const Bitboard FileABB = 0x0101010101010101ULL; |
45 | const Bitboard FileABB = 0x0101010101010101ULL; |
45 | const Bitboard FileBBB = FileABB << 1; |
46 | const Bitboard FileBBB = FileABB << 1; |
46 | const Bitboard FileCBB = FileABB << 2; |
47 | const Bitboard FileCBB = FileABB << 2; |
Line 63... | Line 64... | ||
63 | 64 | ||
64 | extern Bitboard SquareBB[SQUARE_NB]; |
65 | extern Bitboard SquareBB[SQUARE_NB]; |
65 | extern Bitboard FileBB[FILE_NB]; |
66 | extern Bitboard FileBB[FILE_NB]; |
66 | extern Bitboard RankBB[RANK_NB]; |
67 | extern Bitboard RankBB[RANK_NB]; |
67 | extern Bitboard AdjacentFilesBB[FILE_NB]; |
68 | extern Bitboard AdjacentFilesBB[FILE_NB]; |
68 | extern Bitboard |
69 | extern Bitboard ForwardRanksBB[COLOR_NB][RANK_NB]; |
69 | extern Bitboard StepAttacksBB[PIECE_NB][SQUARE_NB]; |
- | |
70 | extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; |
70 | extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; |
71 | extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; |
71 | extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; |
72 | extern Bitboard DistanceRingBB[SQUARE_NB][8]; |
72 | extern Bitboard DistanceRingBB[SQUARE_NB][8]; |
73 | extern Bitboard |
73 | extern Bitboard ForwardFileBB[COLOR_NB][SQUARE_NB]; |
74 | extern Bitboard PassedPawnMask[COLOR_NB][SQUARE_NB]; |
74 | extern Bitboard PassedPawnMask[COLOR_NB][SQUARE_NB]; |
75 | extern Bitboard PawnAttackSpan[COLOR_NB][SQUARE_NB]; |
75 | extern Bitboard PawnAttackSpan[COLOR_NB][SQUARE_NB]; |
76 | extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; |
76 | extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; |
- | 77 | extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; |
|
- | 78 | ||
- | 79 | ||
- | 80 | /// Magic holds all magic bitboards relevant data for a single square |
|
- | 81 | struct Magic { |
|
- | 82 | Bitboard mask; |
|
- | 83 | Bitboard magic; |
|
- | 84 | Bitboard* attacks; |
|
- | 85 | unsigned shift; |
|
- | 86 | ||
- | 87 | // Compute the attack's index using the 'magic bitboards' approach |
|
- | 88 | unsigned index(Bitboard occupied) const { |
|
- | 89 | ||
- | 90 | if (HasPext) |
|
- | 91 | return unsigned(pext(occupied, mask)); |
|
- | 92 | ||
- | 93 | if (Is64Bit) |
|
- | 94 | return unsigned(((occupied & mask) * magic) >> shift); |
|
- | 95 | ||
- | 96 | unsigned lo = unsigned(occupied) & unsigned(mask); |
|
- | 97 | unsigned hi = unsigned(occupied >> 32) & unsigned(mask >> 32); |
|
- | 98 | return (lo * unsigned(magic) ^ hi * unsigned(magic >> 32)) >> shift; |
|
- | 99 | } |
|
- | 100 | }; |
|
- | 101 | ||
- | 102 | extern Magic RookMagics[SQUARE_NB]; |
|
- | 103 | extern Magic BishopMagics[SQUARE_NB]; |
|
77 | 104 | ||
78 | 105 | ||
79 | /// Overloads of bitwise operators between a Bitboard and a Square for testing |
106 | /// Overloads of bitwise operators between a Bitboard and a Square for testing |
80 | /// whether a given bit is set in a bitboard, and for setting and clearing bits. |
107 | /// whether a given bit is set in a bitboard, and for setting and clearing bits. |
81 | 108 | ||
Line 97... | Line 124... | ||
97 | 124 | ||
98 | inline Bitboard& operator^=(Bitboard& b, Square s) { |
125 | inline Bitboard& operator^=(Bitboard& b, Square s) { |
99 | return b ^= SquareBB[s]; |
126 | return b ^= SquareBB[s]; |
100 | } |
127 | } |
101 | 128 | ||
102 |
|
129 | constexpr bool more_than_one(Bitboard b) { |
103 | return b & (b - 1); |
130 | return b & (b - 1); |
104 | } |
131 | } |
105 | - | ||
106 | 132 | ||
107 | /// rank_bb() and file_bb() return a bitboard representing all the squares on |
133 | /// rank_bb() and file_bb() return a bitboard representing all the squares on |
108 | /// the given file or rank. |
134 | /// the given file or rank. |
109 | 135 | ||
110 | inline Bitboard rank_bb(Rank r) { |
136 | inline Bitboard rank_bb(Rank r) { |
Line 124... | Line 150... | ||
124 | } |
150 | } |
125 | 151 | ||
126 | 152 | ||
127 | /// shift() moves a bitboard one step along direction D. Mainly for pawns |
153 | /// shift() moves a bitboard one step along direction D. Mainly for pawns |
128 | 154 | ||
129 | template< |
155 | template<Direction D> |
130 |
|
156 | constexpr Bitboard shift(Bitboard b) { |
131 | return D == NORTH ? b << 8 : D == SOUTH ? b >> 8 |
157 | return D == NORTH ? b << 8 : D == SOUTH ? b >> 8 |
132 | : D == NORTH_EAST ? (b & ~FileHBB) << 9 : D == SOUTH_EAST ? (b & ~FileHBB) >> 7 |
158 | : D == NORTH_EAST ? (b & ~FileHBB) << 9 : D == SOUTH_EAST ? (b & ~FileHBB) >> 7 |
133 | : D == NORTH_WEST ? (b & ~FileABB) << 7 : D == SOUTH_WEST ? (b & ~FileABB) >> 9 |
159 | : D == NORTH_WEST ? (b & ~FileABB) << 7 : D == SOUTH_WEST ? (b & ~FileABB) >> 9 |
134 | : 0; |
160 | : 0; |
135 | } |
161 | } |
Line 151... | Line 177... | ||
151 | inline Bitboard between_bb(Square s1, Square s2) { |
177 | inline Bitboard between_bb(Square s1, Square s2) { |
152 | return BetweenBB[s1][s2]; |
178 | return BetweenBB[s1][s2]; |
153 | } |
179 | } |
154 | 180 | ||
155 | 181 | ||
156 | /// |
182 | /// forward_ranks_bb() returns a bitboard representing all the squares on all the ranks |
157 | /// in front of the given one, from the point of view of the given color. For |
183 | /// in front of the given one, from the point of view of the given color. For |
158 | /// instance, |
184 | /// instance, forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2. |
159 | 185 | ||
160 | inline Bitboard |
186 | inline Bitboard forward_ranks_bb(Color c, Square s) { |
161 | return |
187 | return ForwardRanksBB[c][rank_of(s)]; |
162 | } |
188 | } |
163 | 189 | ||
164 | 190 | ||
165 | /// |
191 | /// forward_file_bb() returns a bitboard representing all the squares along the line |
166 | /// in front of the given one, from the point of view of the given color: |
192 | /// in front of the given one, from the point of view of the given color: |
167 | /// |
193 | /// ForwardFileBB[c][s] = forward_ranks_bb(c, s) & file_bb(s) |
168 | 194 | ||
169 | inline Bitboard |
195 | inline Bitboard forward_file_bb(Color c, Square s) { |
170 | return |
196 | return ForwardFileBB[c][s]; |
171 | } |
197 | } |
172 | 198 | ||
173 | 199 | ||
174 | /// pawn_attack_span() returns a bitboard representing all the squares that can be |
200 | /// pawn_attack_span() returns a bitboard representing all the squares that can be |
175 | /// attacked by a pawn of the given color when it moves along its file, starting |
201 | /// attacked by a pawn of the given color when it moves along its file, starting |
176 | /// from the given square: |
202 | /// from the given square: |
177 | /// |
203 | /// PawnAttackSpan[c][s] = forward_ranks_bb(c, s) & adjacent_files_bb(file_of(s)); |
178 | 204 | ||
179 | inline Bitboard pawn_attack_span(Color c, Square s) { |
205 | inline Bitboard pawn_attack_span(Color c, Square s) { |
180 | return PawnAttackSpan[c][s]; |
206 | return PawnAttackSpan[c][s]; |
181 | } |
207 | } |
182 | 208 | ||
183 | 209 | ||
184 | /// passed_pawn_mask() returns a bitboard mask which can be used to test if a |
210 | /// passed_pawn_mask() returns a bitboard mask which can be used to test if a |
185 | /// pawn of the given color and on the given square is a passed pawn: |
211 | /// pawn of the given color and on the given square is a passed pawn: |
186 | /// |
212 | /// PassedPawnMask[c][s] = pawn_attack_span(c, s) | forward_file_bb(c, s) |
187 | 213 | ||
188 | inline Bitboard passed_pawn_mask(Color c, Square s) { |
214 | inline Bitboard passed_pawn_mask(Color c, Square s) { |
189 | return PassedPawnMask[c][s]; |
215 | return PassedPawnMask[c][s]; |
190 | } |
216 | } |
191 | 217 | ||
Line 208... | Line 234... | ||
208 | template<> inline int distance<File>(Square x, Square y) { return distance(file_of(x), file_of(y)); } |
234 | template<> inline int distance<File>(Square x, Square y) { return distance(file_of(x), file_of(y)); } |
209 | template<> inline int distance<Rank>(Square x, Square y) { return distance(rank_of(x), rank_of(y)); } |
235 | template<> inline int distance<Rank>(Square x, Square y) { return distance(rank_of(x), rank_of(y)); } |
210 | 236 | ||
211 | 237 | ||
212 | /// attacks_bb() returns a bitboard representing all the squares attacked by a |
238 | /// attacks_bb() returns a bitboard representing all the squares attacked by a |
213 | /// piece of type Pt (bishop or rook) placed on 's'. |
239 | /// piece of type Pt (bishop or rook) placed on 's'. |
214 | /// looks up the index using the 'magic bitboards' approach. |
- | |
215 | template<PieceType Pt> |
- | |
216 | inline unsigned magic_index(Square s, Bitboard occupied) { |
- | |
217 | - | ||
218 | extern Bitboard RookMasks[SQUARE_NB]; |
- | |
219 | extern Bitboard RookMagics[SQUARE_NB]; |
- | |
220 | extern unsigned RookShifts[SQUARE_NB]; |
- | |
221 | extern Bitboard BishopMasks[SQUARE_NB]; |
- | |
222 | extern Bitboard BishopMagics[SQUARE_NB]; |
- | |
223 | extern unsigned BishopShifts[SQUARE_NB]; |
- | |
224 | - | ||
225 | Bitboard* const Masks = Pt == ROOK ? RookMasks : BishopMasks; |
- | |
226 | Bitboard* const Magics = Pt == ROOK ? RookMagics : BishopMagics; |
- | |
227 | unsigned* const Shifts = Pt == ROOK ? RookShifts : BishopShifts; |
- | |
228 | - | ||
229 | if (HasPext) |
- | |
230 | return unsigned(pext(occupied, Masks[s])); |
- | |
231 | - | ||
232 | if (Is64Bit) |
- | |
233 | return unsigned(((occupied & Masks[s]) * Magics[s]) >> Shifts[s]); |
- | |
234 | - | ||
235 | unsigned lo = unsigned(occupied) & unsigned(Masks[s]); |
- | |
236 | unsigned hi = unsigned(occupied >> 32) & unsigned(Masks[s] >> 32); |
- | |
237 | return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s]; |
- | |
238 | } |
- | |
239 | 240 | ||
240 | template<PieceType Pt> |
241 | template<PieceType Pt> |
241 | inline Bitboard attacks_bb(Square s, Bitboard occupied) { |
242 | inline Bitboard attacks_bb(Square s, Bitboard occupied) { |
242 | 243 | ||
243 |
|
244 | const Magic& m = Pt == ROOK ? RookMagics[s] : BishopMagics[s]; |
244 |
|
245 | return m.attacks[m.index(occupied)]; |
- | 246 | } |
|
245 | 247 | ||
246 |
|
248 | inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) { |
247 | } |
- | |
248 | 249 | ||
249 |
|
250 | assert(pt != PAWN); |
250 | 251 | ||
251 | switch ( |
252 | switch (pt) |
252 | { |
253 | { |
253 | case BISHOP: return attacks_bb<BISHOP>(s, occupied); |
254 | case BISHOP: return attacks_bb<BISHOP>(s, occupied); |
254 | case ROOK : return attacks_bb<ROOK>(s, occupied); |
255 | case ROOK : return attacks_bb< ROOK>(s, occupied); |
255 | case QUEEN : return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied); |
256 | case QUEEN : return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied); |
256 | default : return |
257 | default : return PseudoAttacks[pt][s]; |
257 | } |
258 | } |
258 | } |
259 | } |
259 | 260 | ||
260 | 261 | ||
261 | /// popcount() counts the number of non-zero bits in a bitboard |
262 | /// popcount() counts the number of non-zero bits in a bitboard |
Line 289... | Line 290... | ||
289 | return Square(__builtin_ctzll(b)); |
290 | return Square(__builtin_ctzll(b)); |
290 | } |
291 | } |
291 | 292 | ||
292 | inline Square msb(Bitboard b) { |
293 | inline Square msb(Bitboard b) { |
293 | assert(b); |
294 | assert(b); |
294 | return Square(63 |
295 | return Square(63 ^ __builtin_clzll(b)); |
295 | } |
296 | } |
296 | 297 | ||
297 | #elif defined(_WIN64) && defined(_MSC_VER) |
298 | #elif defined(_WIN64) && defined(_MSC_VER) |
298 | 299 | ||
299 | inline Square lsb(Bitboard b) { |
300 | inline Square lsb(Bitboard b) { |