Line data Source code
1 : #pragma once
2 :
3 : #include "definition.hpp"
4 :
5 : /*!
6 : * Main bitboard utilities
7 : * especially countBit (using POPCOUNT) and popBit (bsf)
8 : * are optimized for the platform being used
9 : */
10 :
11 : #ifdef __MINGW32__
12 : #define POPCOUNT(x) static_cast<int>(__builtin_popcountll(x))
13 : FORCE_FINLINE int bitScanForward(BitBoard bb) {
14 : assert(isNotEmpty(bb));
15 : return __builtin_ctzll(bb);
16 : }
17 : #define bsf(x, i) (i = bitScanForward(x))
18 : #define swapbits(x) (__builtin_bswap64(x))
19 : #define swapbits32(x) (__builtin_bswap32(x))
20 : #else // __MINGW32__
21 : #ifdef _WIN32
22 : #ifdef _WIN64
23 : #define POPCOUNT(x) __popcnt64(x)
24 : #define bsf(x, i) _BitScanForward64(&i, x)
25 : #define swapbits(x) (_byteswap_uint64(x))
26 : #define swapbits32(x) (_byteswap_ulong(x))
27 : #else // we are _WIN32 but not _WIN64
28 : FORCE_FINLINE int popcount(uint64_t b) {
29 : b = (b & 0x5555555555555555LU) + (b >> 1 & 0x5555555555555555LU);
30 : b = (b & 0x3333333333333333LU) + (b >> 2 & 0x3333333333333333LU);
31 : b = b + (b >> 4) & 0x0F0F0F0F0F0F0F0FLU;
32 : b = b + (b >> 8);
33 : b = b + (b >> 16);
34 : b = b + (b >> 32) & 0x0000007F;
35 : return static_cast<int>(b);
36 : }
37 : FORCE_FINLINE const int index64[NbSquare] = {
38 : 0, 1, 48, 2, 57, 49, 28, 3,
39 : 61, 58, 50, 42, 38, 29, 17, 4,
40 : 62, 55, 59, 36, 53, 51, 43, 22,
41 : 45, 39, 33, 30, 24, 18, 12, 5,
42 : 63, 47, 56, 27, 60, 41, 37, 16,
43 : 54, 35, 52, 21, 44, 32, 23, 11,
44 : 46, 26, 40, 15, 34, 20, 31, 10,
45 : 25, 14, 19, 9, 13, 8, 7, 6
46 : };
47 : FORCE_FINLINE int bitScanForward(int64_t bb) {
48 : const uint64_t debruijn64 = 0x03f79d71b4cb0a89;
49 : assert(isNotEmpty(bb));
50 : return index64[((bb & -bb) * debruijn64) >> 58];
51 : }
52 : #define POPCOUNT(x) popcount(x)
53 : #define bsf(x, i) (i = bitScanForward(x))
54 : #define swapbits(x) (_byteswap_uint64(x))
55 : #define swapbits32(x) (_byteswap_ulong(x))
56 : #endif // _WIN64
57 : #else // _WIN32 (thus linux)
58 : #define POPCOUNT(x) static_cast<int>(__builtin_popcountll(x))
59 : FORCE_FINLINE int bitScanForward(BitBoard bb) {
60 : assert(isNotEmpty(bb));
61 741268865 : return __builtin_ctzll(bb);
62 : }
63 : #define bsf(x, i) (i = bitScanForward(x))
64 : #define swapbits(x) (__builtin_bswap64(x))
65 : #define swapbits32(x) (__builtin_bswap32(x))
66 : #endif // linux
67 : #endif // __MINGW32__
68 :
69 : // Hard to say which one is better (SquareToBitboardTable or SquareToBitboard), bit shifting or precalculated access to mask data ...
70 : constexpr auto SquareToBitboard(const Square k) {
71 335847161 : assert(isValidSquare(k));
72 343975455 : return static_cast<BitBoard>(1ull << k);
73 : }
74 :
75 : namespace BB {
76 :
77 : enum BBSq : BitBoard { BBSq_a1 = SquareToBitboard(Sq_a1),BBSq_b1 = SquareToBitboard(Sq_b1),BBSq_c1 = SquareToBitboard(Sq_c1),BBSq_d1 = SquareToBitboard(Sq_d1),BBSq_e1 = SquareToBitboard(Sq_e1),BBSq_f1 = SquareToBitboard(Sq_f1),BBSq_g1 = SquareToBitboard(Sq_g1),BBSq_h1 = SquareToBitboard(Sq_h1),
78 : BBSq_a2 = SquareToBitboard(Sq_a2),BBSq_b2 = SquareToBitboard(Sq_b2),BBSq_c2 = SquareToBitboard(Sq_c2),BBSq_d2 = SquareToBitboard(Sq_d2),BBSq_e2 = SquareToBitboard(Sq_e2),BBSq_f2 = SquareToBitboard(Sq_f2),BBSq_g2 = SquareToBitboard(Sq_g2),BBSq_h2 = SquareToBitboard(Sq_h2),
79 : BBSq_a3 = SquareToBitboard(Sq_a3),BBSq_b3 = SquareToBitboard(Sq_b3),BBSq_c3 = SquareToBitboard(Sq_c3),BBSq_d3 = SquareToBitboard(Sq_d3),BBSq_e3 = SquareToBitboard(Sq_e3),BBSq_f3 = SquareToBitboard(Sq_f3),BBSq_g3 = SquareToBitboard(Sq_g3),BBSq_h3 = SquareToBitboard(Sq_h3),
80 : BBSq_a4 = SquareToBitboard(Sq_a4),BBSq_b4 = SquareToBitboard(Sq_b4),BBSq_c4 = SquareToBitboard(Sq_c4),BBSq_d4 = SquareToBitboard(Sq_d4),BBSq_e4 = SquareToBitboard(Sq_e4),BBSq_f4 = SquareToBitboard(Sq_f4),BBSq_g4 = SquareToBitboard(Sq_g4),BBSq_h4 = SquareToBitboard(Sq_h4),
81 : BBSq_a5 = SquareToBitboard(Sq_a5),BBSq_b5 = SquareToBitboard(Sq_b5),BBSq_c5 = SquareToBitboard(Sq_c5),BBSq_d5 = SquareToBitboard(Sq_d5),BBSq_e5 = SquareToBitboard(Sq_e5),BBSq_f5 = SquareToBitboard(Sq_f5),BBSq_g5 = SquareToBitboard(Sq_g5),BBSq_h5 = SquareToBitboard(Sq_h5),
82 : BBSq_a6 = SquareToBitboard(Sq_a6),BBSq_b6 = SquareToBitboard(Sq_b6),BBSq_c6 = SquareToBitboard(Sq_c6),BBSq_d6 = SquareToBitboard(Sq_d6),BBSq_e6 = SquareToBitboard(Sq_e6),BBSq_f6 = SquareToBitboard(Sq_f6),BBSq_g6 = SquareToBitboard(Sq_g6),BBSq_h6 = SquareToBitboard(Sq_h6),
83 : BBSq_a7 = SquareToBitboard(Sq_a7),BBSq_b7 = SquareToBitboard(Sq_b7),BBSq_c7 = SquareToBitboard(Sq_c7),BBSq_d7 = SquareToBitboard(Sq_d7),BBSq_e7 = SquareToBitboard(Sq_e7),BBSq_f7 = SquareToBitboard(Sq_f7),BBSq_g7 = SquareToBitboard(Sq_g7),BBSq_h7 = SquareToBitboard(Sq_h7),
84 : BBSq_a8 = SquareToBitboard(Sq_a8),BBSq_b8 = SquareToBitboard(Sq_b8),BBSq_c8 = SquareToBitboard(Sq_c8),BBSq_d8 = SquareToBitboard(Sq_d8),BBSq_e8 = SquareToBitboard(Sq_e8),BBSq_f8 = SquareToBitboard(Sq_f8),BBSq_g8 = SquareToBitboard(Sq_g8),BBSq_h8 = SquareToBitboard(Sq_h8)};
85 :
86 : inline constexpr BitBoard whiteSquare = 0x55AA55AA55AA55AA;
87 : inline constexpr BitBoard blackSquare = 0xAA55AA55AA55AA55;
88 : //inline constexpr BitBoard whiteSideSquare = 0x00000000FFFFFFFF;
89 : //inline constexpr BitBoard blackSideSquare = 0xFFFFFFFF00000000;
90 : inline constexpr BitBoard fileA = 0x0101010101010101;
91 : inline constexpr BitBoard fileB = 0x0202020202020202;
92 : inline constexpr BitBoard fileC = 0x0404040404040404;
93 : inline constexpr BitBoard fileD = 0x0808080808080808;
94 : inline constexpr BitBoard fileE = 0x1010101010101010;
95 : inline constexpr BitBoard fileF = 0x2020202020202020;
96 : inline constexpr BitBoard fileG = 0x4040404040404040;
97 : inline constexpr BitBoard fileH = 0x8080808080808080;
98 : inline constexpr array1d<BitBoard,8> files = {fileA, fileB, fileC, fileD, fileE, fileF, fileG, fileH};
99 : inline constexpr BitBoard rank1 = 0x00000000000000ff;
100 : inline constexpr BitBoard rank2 = 0x000000000000ff00;
101 : inline constexpr BitBoard rank3 = 0x0000000000ff0000;
102 : inline constexpr BitBoard rank4 = 0x00000000ff000000;
103 : inline constexpr BitBoard rank5 = 0x000000ff00000000;
104 : inline constexpr BitBoard rank6 = 0x0000ff0000000000;
105 : inline constexpr BitBoard rank7 = 0x00ff000000000000;
106 : inline constexpr BitBoard rank8 = 0xff00000000000000;
107 : inline constexpr array1d<BitBoard,8> ranks = {rank1, rank2, rank3, rank4, rank5, rank6, rank7, rank8};
108 : //inline constexpr BitBoard diagA1H8 = 0x8040201008040201;
109 : //inline constexpr BitBoard diagA8H1 = 0x0102040810204080;
110 : //inline constexpr BitBoard center = BBSq_d4 | BBSq_d5 | BBSq_e4 | BBSq_e5;
111 : inline constexpr BitBoard advancedRanks = 0x0000ffffffff0000;
112 : inline constexpr BitBoard rank1_or_rank8 = BB::rank1 | BB::rank8;
113 : inline constexpr BitBoard extendedCenter = BBSq_c3 | BBSq_c4 | BBSq_c5 | BBSq_c6 |
114 : BBSq_d3 | BBSq_d4 | BBSq_d5 | BBSq_d6 |
115 : BBSq_e3 | BBSq_e4 | BBSq_e5 | BBSq_e6 |
116 : BBSq_f3 | BBSq_f4 | BBSq_f5 | BBSq_f6;
117 :
118 : inline constexpr colored<BitBoard> seventhRank = {rank7, rank2};
119 :
120 : inline constexpr colored<BitBoard> holesZone = {rank2 | rank3 | rank4 | rank5, rank4 | rank5 | rank6 | rank7};
121 : inline constexpr BitBoard queenSide = fileA | fileB | fileC | fileD;
122 : inline constexpr BitBoard centerFiles = fileC | fileD | fileE | fileF;
123 : inline constexpr BitBoard kingSide = fileE | fileF | fileG | fileH;
124 : inline constexpr array1d<BitBoard,8> kingFlank = {queenSide ^ fileD, queenSide, queenSide, centerFiles, centerFiles, kingSide, kingSide, kingSide ^ fileE};
125 :
126 179498734 : FORCE_FINLINE void _setBit (BitBoard& b, const Square k) { b |= SquareToBitboard(k); }
127 190502464 : FORCE_FINLINE void _unSetBit(BitBoard& b, const Square k) { b &= ~SquareToBitboard(k); }
128 :
129 195116878 : [[nodiscard]] FORCE_FINLINE ScoreType countBit(const BitBoard& b) { return ScoreType(POPCOUNT(b)); }
130 :
131 : [[nodiscard]] FORCE_FINLINE Square popBit(BitBoard& b) {
132 : assert(isNotEmpty(b));
133 : #ifdef _WIN64
134 : unsigned long i = 0ull;
135 : #else
136 : int i = 0;
137 : #endif
138 : bsf(b, i);
139 209167387 : b &= b - 1;
140 581967193 : return static_cast<Square>(i);
141 : }
142 :
143 : // This function **won't** consume the given bitboard as it is passed by copy !
144 : template<typename F>
145 : FORCE_FINLINE void applyOn(BitBoard b, const F f){
146 1182039966 : while(b){
147 598971296 : f(popBit(b));
148 : }
149 : }
150 :
151 : /*
152 : [[nodiscard]] constexpr bool moreThanOne(const BitBoard b) {
153 : return b & (b - 1);
154 : }
155 : */
156 :
157 : } // namespace BB
|