Rev 96 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 96 | Rev 154 | ||
---|---|---|---|
Line 58... | Line 58... | ||
58 | const Bitboard Rank6BB = Rank1BB << (8 * 5); |
58 | const Bitboard Rank6BB = Rank1BB << (8 * 5); |
59 | const Bitboard Rank7BB = Rank1BB << (8 * 6); |
59 | const Bitboard Rank7BB = Rank1BB << (8 * 6); |
60 | const Bitboard Rank8BB = Rank1BB << (8 * 7); |
60 | const Bitboard Rank8BB = Rank1BB << (8 * 7); |
61 | 61 | ||
62 | extern int SquareDistance[SQUARE_NB][SQUARE_NB]; |
62 | extern int SquareDistance[SQUARE_NB][SQUARE_NB]; |
63 | - | ||
64 | extern Bitboard RookMasks [SQUARE_NB]; |
- | |
65 | extern Bitboard RookMagics [SQUARE_NB]; |
- | |
66 | extern Bitboard* RookAttacks[SQUARE_NB]; |
- | |
67 | extern unsigned RookShifts [SQUARE_NB]; |
- | |
68 | - | ||
69 | extern Bitboard BishopMasks [SQUARE_NB]; |
- | |
70 | extern Bitboard BishopMagics [SQUARE_NB]; |
- | |
71 | extern Bitboard* BishopAttacks[SQUARE_NB]; |
- | |
72 | extern unsigned BishopShifts [SQUARE_NB]; |
- | |
73 | 63 | ||
74 | extern Bitboard SquareBB[SQUARE_NB]; |
64 | extern Bitboard SquareBB[SQUARE_NB]; |
75 | extern Bitboard FileBB[FILE_NB]; |
65 | extern Bitboard FileBB[FILE_NB]; |
76 | extern Bitboard RankBB[RANK_NB]; |
66 | extern Bitboard RankBB[RANK_NB]; |
77 | extern Bitboard AdjacentFilesBB[FILE_NB]; |
67 | extern Bitboard AdjacentFilesBB[FILE_NB]; |
Line 132... | Line 122... | ||
132 | inline Bitboard file_bb(Square s) { |
122 | inline Bitboard file_bb(Square s) { |
133 | return FileBB[file_of(s)]; |
123 | return FileBB[file_of(s)]; |
134 | } |
124 | } |
135 | 125 | ||
136 | 126 | ||
137 | /// |
127 | /// shift() moves a bitboard one step along direction D. Mainly for pawns |
138 | 128 | ||
139 | template<Square |
129 | template<Square D> |
140 | inline Bitboard |
130 | inline Bitboard shift(Bitboard b) { |
141 | return |
131 | return D == NORTH ? b << 8 : D == SOUTH ? b >> 8 |
142 | : |
132 | : D == NORTH_EAST ? (b & ~FileHBB) << 9 : D == SOUTH_EAST ? (b & ~FileHBB) >> 7 |
143 | : |
133 | : D == NORTH_WEST ? (b & ~FileABB) << 7 : D == SOUTH_WEST ? (b & ~FileABB) >> 9 |
144 | : 0; |
134 | : 0; |
145 | } |
135 | } |
146 | 136 | ||
147 | 137 | ||
148 | /// adjacent_files_bb() returns a bitboard representing all the squares on the |
138 | /// adjacent_files_bb() returns a bitboard representing all the squares on the |
Line 222... | Line 212... | ||
222 | /// attacks_bb() returns a bitboard representing all the squares attacked by a |
212 | /// attacks_bb() returns a bitboard representing all the squares attacked by a |
223 | /// piece of type Pt (bishop or rook) placed on 's'. The helper magic_index() |
213 | /// piece of type Pt (bishop or rook) placed on 's'. The helper magic_index() |
224 | /// looks up the index using the 'magic bitboards' approach. |
214 | /// looks up the index using the 'magic bitboards' approach. |
225 | template<PieceType Pt> |
215 | template<PieceType Pt> |
226 | inline unsigned magic_index(Square s, Bitboard occupied) { |
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]; |
|
227 | 224 | ||
228 | Bitboard* const Masks = Pt == ROOK ? RookMasks : BishopMasks; |
225 | Bitboard* const Masks = Pt == ROOK ? RookMasks : BishopMasks; |
229 | Bitboard* const Magics = Pt == ROOK ? RookMagics : BishopMagics; |
226 | Bitboard* const Magics = Pt == ROOK ? RookMagics : BishopMagics; |
230 | unsigned* const Shifts = Pt == ROOK ? RookShifts : BishopShifts; |
227 | unsigned* const Shifts = Pt == ROOK ? RookShifts : BishopShifts; |
231 | 228 | ||
Line 240... | Line 237... | ||
240 | return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s]; |
237 | return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s]; |
241 | } |
238 | } |
242 | 239 | ||
243 | template<PieceType Pt> |
240 | template<PieceType Pt> |
244 | inline Bitboard attacks_bb(Square s, Bitboard occupied) { |
241 | inline Bitboard attacks_bb(Square s, Bitboard occupied) { |
- | 242 | ||
- | 243 | extern Bitboard* RookAttacks[SQUARE_NB]; |
|
- | 244 | extern Bitboard* BishopAttacks[SQUARE_NB]; |
|
- | 245 | ||
245 | return (Pt == ROOK ? RookAttacks : BishopAttacks)[s][magic_index<Pt>(s, occupied)]; |
246 | return (Pt == ROOK ? RookAttacks : BishopAttacks)[s][magic_index<Pt>(s, occupied)]; |
246 | } |
247 | } |
247 | 248 | ||
248 | inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) { |
249 | inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) { |
249 | 250 | ||
Line 255... | Line 256... | ||
255 | default : return StepAttacksBB[pc][s]; |
256 | default : return StepAttacksBB[pc][s]; |
256 | } |
257 | } |
257 | } |
258 | } |
258 | 259 | ||
259 | 260 | ||
260 | /// |
261 | /// popcount() counts the number of non-zero bits in a bitboard |
261 | 262 | ||
262 |
|
263 | inline int popcount(Bitboard b) { |
263 | 264 | ||
264 |
|
265 | #ifndef USE_POPCNT |
265 | 266 | ||
266 | inline Square lsb(Bitboard b) { |
- | |
267 |
|
267 | extern uint8_t PopCnt16[1 << 16]; |
268 |
|
268 | union { Bitboard bb; uint16_t u[4]; } v = { b }; |
269 | return |
269 | return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]]; |
270 | } |
- | |
271 | 270 | ||
272 |
|
271 | #elif defined(_MSC_VER) || defined(__INTEL_COMPILER) |
273 | unsigned long idx; |
- | |
274 | _BitScanReverse64(&idx, b); |
- | |
275 | return (Square) idx; |
- | |
276 | } |
- | |
277 | 272 | ||
278 |
|
273 | return (int)_mm_popcnt_u64(b); |
279 | 274 | ||
280 | inline int lsb32(uint32_t v) { |
- | |
281 |
|
275 | #else // Assumed gcc or compatible compiler |
282 | return __builtin_clz(v); |
- | |
283 | } |
- | |
284 | 276 | ||
285 | inline Square msb(Bitboard b) { |
- | |
286 | return |
277 | return __builtin_popcountll(b); |
- | 278 | ||
- | 279 | #endif |
|
287 | } |
280 | } |
- | 281 | ||
- | 282 | ||
- | 283 | /// lsb() and msb() return the least/most significant bit in a non-zero bitboard |
|
- | 284 | ||
- | 285 | #if defined(__GNUC__) |
|
288 | 286 | ||
289 | inline Square lsb(Bitboard b) { |
287 | inline Square lsb(Bitboard b) { |
- | 288 | assert(b); |
|
290 | return |
289 | return Square(__builtin_ctzll(b)); |
291 | } |
290 | } |
292 | 291 | ||
- | 292 | inline Square msb(Bitboard b) { |
|
- | 293 | assert(b); |
|
293 |
|
294 | return Square(63 - __builtin_clzll(b)); |
- | 295 | } |
|
294 | 296 | ||
- | 297 | #elif defined(_WIN64) && defined(_MSC_VER) |
|
- | 298 | ||
295 | inline Square lsb(Bitboard b) { |
299 | inline Square lsb(Bitboard b) { |
- | 300 | assert(b); |
|
296 |
|
301 | unsigned long idx; |
297 |
|
302 | _BitScanForward64(&idx, b); |
298 | return (Square) idx; |
303 | return (Square) idx; |
299 | } |
304 | } |
300 | 305 | ||
301 | inline Square msb(Bitboard b) { |
306 | inline Square msb(Bitboard b) { |
- | 307 | assert(b); |
|
302 |
|
308 | unsigned long idx; |
303 |
|
309 | _BitScanReverse64(&idx, b); |
304 | return (Square) idx; |
310 | return (Square) idx; |
305 | } |
311 | } |
306 | 312 | ||
307 |
|
313 | #else |
308 | 314 | ||
309 |
|
315 | #define NO_BSF // Fallback on software implementation for other cases |
310 | 316 | ||
311 | Square lsb(Bitboard b); |
317 | Square lsb(Bitboard b); |
312 | Square msb(Bitboard b); |
318 | Square msb(Bitboard b); |
313 | 319 | ||
314 | #endif |
320 | #endif |