-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitboard.hpp
153 lines (125 loc) · 3.26 KB
/
bitboard.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#pragma once
#include <array>
#include <vector>
#include <cassert>
#include <cinttypes>
#include <bitset>
#include <string>
#include "constants.hpp"
#include "util.hpp"
namespace bitboard
{
typedef std::uint64_t Bitboard;
constexpr bool hasBitAt(const Bitboard board, int position)
{
assert(position >= 0 && position < constants::SQUARES_AMOUNT);
return (board >> position) & 1;
}
constexpr Bitboard setBitAt(Bitboard board, int position)
{
assert(position >= 0 && position < constants::SQUARES_AMOUNT);
return board | (static_cast<uint64_t>(1ULL) << position);
}
constexpr Bitboard clearBitAt(Bitboard board, int position)
{
assert(position >= 0 && position < constants::SQUARES_AMOUNT);
return board & ~(static_cast<uint64_t>(1ULL) << position);
}
constexpr Bitboard mask(Bitboard board, Bitboard mask)
{
return board & mask;
}
constexpr Bitboard swapMask(Bitboard board, Bitboard mask)
{
return board ^ mask;
}
inline std::string toString(Bitboard board)
{
std::string s;
for (int rank = asInt(constants::Rank::_8); rank >= asInt(constants::Rank::_1); --rank)
{
for (int file = asInt(constants::File::A); file <= asInt(constants::File::H); file++)
{
int square = util::_120xyToSquare(file, rank);
int _64_square = util::_120To64(square);
if (hasBitAt(board, _64_square))
{
s += "1 ";
}
else
{
s += "0 ";
}
}
s += "\n";
}
return s;
}
#ifdef USE_ASM
# ifndef _MSC_VER
inline int bitscanForward(uint64_t x)
{
uint64_t r;
asm(
"bsf %[x],%[r];"
: [ r ] "=a"(r)
: [ x ] "r"(x)
);
return r;
}
inline int bitscanReverse(uint64_t x)--
{
uint64_t r;
asm(
"bsr %[x],%[r];"
: [ r ] "=a"(r)
: [ x ] "r"(x));
return r;
}
# else
inline int bitscanForward(uint64_t x) {
unsigned long result = -1;
_BitScanForward64(&result, x);
return result;
}
inline int bitscanReverse(uint64_t x) {
unsigned long result = -1;
_BitScanReverse64(&result, x);
return result;
}
# endif
#else
#pragma message("USE_ASM not defined: Using slow alternative implementation of bitscan.")
inline int bitscanForward(uint64_t x)
{
int result = 0;
while ((x & 1) == 0)
{
x >>= 1;
++result;
}
return result;
}
inline int bitscanReverse(uint64_t x)
{
int result = 0;
while ((x & (0ULL | 1ULL << 63)) == 0)
{
x <<= 1;
++result;
}
return result;
}
#endif
inline int countBits(Bitboard board)
{
int bit_count = 0;
Bitboard current_board = board;
while (current_board)
{
current_board = current_board >> (1 + bitscanForward(current_board));
bit_count++;
}
return bit_count;
}
} // namespace bitboard