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 |