-
Notifications
You must be signed in to change notification settings - Fork 2
/
Bitboard.h
144 lines (128 loc) · 3.68 KB
/
Bitboard.h
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
#ifndef LIBCHESS_BITBOARD_H
#define LIBCHESS_BITBOARD_H
#include <cstdint>
#include <iostream>
#include <optional>
#include "Square.h"
namespace libchess {
class Bitboard {
public:
using value_type = std::uint64_t;
constexpr Bitboard() : value_(0) {
}
constexpr explicit Bitboard(int shift) : value_(std::uint64_t(1) << shift) {
}
constexpr explicit Bitboard(unsigned shift) : value_(std::uint64_t(1) << shift) {
}
constexpr explicit Bitboard(value_type value) : value_(value) {
}
constexpr explicit Bitboard(Square square) : Bitboard(square.value()) {
}
constexpr operator value_type() const {
return value_;
}
constexpr Bitboard operator<<(int shift) const {
return Bitboard{value_ << unsigned(shift)};
}
constexpr Bitboard operator<<(unsigned shift) const {
return Bitboard{value_ << shift};
}
constexpr Bitboard operator>>(int shift) const {
return Bitboard{value_ >> unsigned(shift)};
}
constexpr Bitboard operator>>(unsigned shift) const {
return Bitboard{value_ >> shift};
}
constexpr Bitboard operator|(value_type rhs) const {
return Bitboard{value_ | rhs};
}
constexpr Bitboard operator&(value_type rhs) const {
return Bitboard{value_ & rhs};
}
constexpr Bitboard operator^(value_type rhs) const {
return Bitboard{value_ ^ rhs};
}
constexpr Bitboard operator|(Bitboard rhs) const {
return Bitboard{value_ | rhs};
}
constexpr Bitboard operator&(Bitboard rhs) const {
return Bitboard{value_ & rhs};
}
constexpr Bitboard operator^(Bitboard rhs) const {
return Bitboard{value_ ^ rhs};
}
constexpr Bitboard operator~() const {
return Bitboard{~value_};
}
constexpr bool operator!() const {
return value_ == 0;
}
constexpr Bitboard operator-() const {
return Bitboard{~value_};
}
constexpr Bitboard& operator<<=(int shift) {
value_ <<= unsigned(shift);
return *this;
}
constexpr Bitboard& operator<<=(unsigned shift) {
value_ <<= shift;
return *this;
}
constexpr Bitboard& operator>>=(int shift) {
value_ >>= unsigned(shift);
return *this;
}
constexpr Bitboard& operator>>=(unsigned shift) {
value_ >>= shift;
return *this;
}
constexpr Bitboard& operator|=(value_type rhs) {
value_ |= rhs;
return *this;
}
constexpr Bitboard& operator&=(value_type rhs) {
value_ &= rhs;
return *this;
}
constexpr Bitboard& operator^=(value_type rhs) {
value_ ^= rhs;
return *this;
}
constexpr int popcount() const {
return __builtin_popcountll(value_);
}
constexpr Square forward_bitscan() const {
return Square{__builtin_ctzll(value_)};
}
constexpr Square reverse_bitscan() const {
return Square{63 - __builtin_clzll(value_)};
}
constexpr void forward_popbit() {
value_ &= value_ - 1;
}
constexpr void reverse_popbit() {
value_ ^= Bitboard{reverse_bitscan() + 1};
}
private:
value_type value_;
};
inline std::ostream& operator<<(std::ostream& ostream, Bitboard bb) {
for (unsigned sq = 0; sq < 64; ++sq) {
if (sq && !(sq & 7u)) {
ostream << "\n";
}
if (Bitboard(sq ^ 56u) & bb) {
ostream << "X ";
} else {
ostream << "- ";
}
}
ostream << "\n";
return ostream;
}
} // namespace libchess
namespace std {
template <>
struct hash<libchess::Bitboard> : public hash<libchess::Bitboard::value_type> {};
} // namespace std
#endif // LIBCHESS_BITBOARD_H