295 lines
8.4 KiB
C++
295 lines
8.4 KiB
C++
#ifndef CHESS_ENGINE_BITBOARD_HPP
|
|
#define CHESS_ENGINE_BITBOARD_HPP
|
|
|
|
#include <cstdint>
|
|
#include <ostream>
|
|
#include "Square.hpp"
|
|
|
|
enum DefinedBoards : uint64_t {
|
|
AFile = 0x0101010101010101,
|
|
BFile = AFile << 1,
|
|
CFile = AFile << 2,
|
|
DFile = AFile << 3,
|
|
EFile = AFile << 4,
|
|
FFile = AFile << 5,
|
|
GFile = AFile << 6,
|
|
HFile = AFile << 7,
|
|
Rank1 = 0x00000000000000FF,
|
|
Rank2 = Rank1 << 8,
|
|
Rank3 = Rank1 << 16,
|
|
Rank4 = Rank1 << 24,
|
|
Rank5 = Rank1 << 32,
|
|
Rank6 = Rank1 << 40,
|
|
Rank7 = Rank1 << 48,
|
|
Rank8 = Rank1 << 56,
|
|
WhiteCastlingRank = (1ULL << A2) - 1,
|
|
BlackCastlingRank = (~1ULL << H7),
|
|
CastlingRanks = WhiteCastlingRank | BlackCastlingRank,
|
|
CastlingSquares = (WhiteCastlingRank | BlackCastlingRank) & (CFile | GFile),
|
|
};
|
|
|
|
class BitBoard final {
|
|
|
|
public:
|
|
|
|
using U64 = uint64_t;
|
|
|
|
BitBoard(U64 v = 0);
|
|
|
|
explicit constexpr operator bool() const {
|
|
return mBoard != 0;
|
|
}
|
|
explicit constexpr operator unsigned int() const {
|
|
return mBoard;
|
|
}
|
|
explicit constexpr operator unsigned long() const {
|
|
return mBoard;
|
|
}
|
|
explicit constexpr operator unsigned long long() const {
|
|
return mBoard;
|
|
}
|
|
operator void *() const {
|
|
return (void *) mBoard;
|
|
}
|
|
|
|
// Relational operators
|
|
constexpr bool operator==(const BitBoard &rhs) const;
|
|
constexpr bool operator!=(const BitBoard &rhs) const;
|
|
constexpr bool operator<(const BitBoard &rhs) const;
|
|
constexpr bool operator>(const BitBoard &rhs) const;
|
|
constexpr bool operator<=(const BitBoard &rhs) const;
|
|
constexpr bool operator>=(const BitBoard &rhs) const;
|
|
|
|
// Logical operators
|
|
constexpr bool operator!() const;
|
|
constexpr bool operator&&(const BitBoard &rhs) const;
|
|
constexpr bool operator||(const BitBoard &rhs) const;
|
|
|
|
// Bitwise operators
|
|
constexpr BitBoard &operator&=(const BitBoard &rhs);
|
|
constexpr BitBoard &operator|=(const BitBoard &rhs);
|
|
constexpr BitBoard &operator^=(const BitBoard &rhs);
|
|
constexpr BitBoard &operator<<=(const BitBoard &rhs);
|
|
constexpr BitBoard &operator>>=(const BitBoard &rhs);
|
|
BitBoard operator~() const {
|
|
BitBoard result(*this);
|
|
result.mBoard = ~mBoard;
|
|
return result;
|
|
}
|
|
friend BitBoard operator^(const BitBoard &lhs, const BitBoard &rhs);
|
|
friend BitBoard operator|(const BitBoard &lhs, const BitBoard &rhs);
|
|
friend BitBoard operator&(const BitBoard &lhs, const BitBoard &rhs);
|
|
friend BitBoard operator<<(const BitBoard &lhs, const BitBoard &rhs);
|
|
friend BitBoard operator>>(const BitBoard &lhs, const BitBoard &rhs);
|
|
|
|
// Arithmetic operators
|
|
constexpr BitBoard &operator+=(const BitBoard &rhs);
|
|
constexpr BitBoard &operator-=(const BitBoard &rhs);
|
|
constexpr BitBoard &operator%=(const BitBoard &rhs);
|
|
friend BitBoard operator+(const BitBoard &lhs, const BitBoard &rhs);
|
|
friend BitBoard operator-(const BitBoard &lhs, const BitBoard &rhs);
|
|
friend BitBoard operator%(const BitBoard &lhs, const BitBoard &rhs);
|
|
|
|
// Stream operator
|
|
friend std::ostream &operator<<(std::ostream &os, const BitBoard &board);
|
|
|
|
constexpr void clear(unsigned i);
|
|
constexpr void set(unsigned i);
|
|
|
|
BitBoard north() const;
|
|
BitBoard northEast() const;
|
|
BitBoard northWest() const;
|
|
BitBoard east() const;
|
|
BitBoard south() const;
|
|
BitBoard southEast() const;
|
|
BitBoard southWest() const;
|
|
BitBoard west() const;
|
|
|
|
BitBoard northFill() const;
|
|
BitBoard southFill() const;
|
|
BitBoard fileFill() const;
|
|
|
|
static BitBoard bishopAttacks(BitBoard pos, BitBoard empty);
|
|
static BitBoard rookAttacks(BitBoard rooks, BitBoard empty);
|
|
static BitBoard queenAttacks(BitBoard queens, BitBoard empty);
|
|
static BitBoard kingMoves(const BitBoard kings);
|
|
static BitBoard castlingMoves(BitBoard kings, BitBoard rooks, BitBoard empty);
|
|
static BitBoard knightMoves(BitBoard knights);
|
|
|
|
static BitBoard pawnNorthAttacks(BitBoard pawns, BitBoard targets);
|
|
static BitBoard pawnSouthAttacks(BitBoard pawns, BitBoard targets);
|
|
|
|
static BitBoard pawnNorthMoves(BitBoard pawns, BitBoard empty);
|
|
static BitBoard pawnSouthMoves(BitBoard pawns, BitBoard empty);
|
|
|
|
static BitBoard fromIndex(unsigned i);
|
|
|
|
// Returns the number of trailing 0-bits in b.
|
|
// WARN: Check for 0!
|
|
unsigned lsb() const;
|
|
unsigned pop();
|
|
constexpr int count() const;
|
|
|
|
private:
|
|
U64 mBoard = 0;
|
|
};
|
|
|
|
// Relational operators
|
|
constexpr bool BitBoard::operator==(const BitBoard &rhs) const {
|
|
return mBoard == rhs.mBoard;
|
|
}
|
|
constexpr bool BitBoard::operator!=(const BitBoard &rhs) const {
|
|
return !(rhs == *this);
|
|
}
|
|
constexpr bool BitBoard::operator<(const BitBoard &rhs) const {
|
|
return mBoard < rhs.mBoard;
|
|
}
|
|
constexpr bool BitBoard::operator>(const BitBoard &rhs) const {
|
|
return rhs < *this;
|
|
}
|
|
constexpr bool BitBoard::operator<=(const BitBoard &rhs) const {
|
|
return !(rhs < *this);
|
|
}
|
|
constexpr bool BitBoard::operator>=(const BitBoard &rhs) const {
|
|
return !(*this < rhs);
|
|
}
|
|
|
|
// Logical operators
|
|
constexpr bool BitBoard::operator!() const {
|
|
return !mBoard;
|
|
}
|
|
constexpr bool BitBoard::operator&&(const BitBoard &rhs) const {
|
|
return mBoard && rhs.mBoard;
|
|
}
|
|
constexpr bool BitBoard::operator||(const BitBoard &rhs) const {
|
|
return mBoard || rhs.mBoard;
|
|
}
|
|
|
|
// Bitwise operators
|
|
constexpr BitBoard &BitBoard::operator&=(const BitBoard &rhs) {
|
|
mBoard &= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
constexpr BitBoard &BitBoard::operator|=(const BitBoard &rhs) {
|
|
mBoard |= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
constexpr BitBoard &BitBoard::operator^=(const BitBoard &rhs) {
|
|
mBoard ^= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
constexpr BitBoard &BitBoard::operator<<=(const BitBoard &rhs) {
|
|
mBoard <<= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
constexpr BitBoard &BitBoard::operator>>=(const BitBoard &rhs) {
|
|
mBoard >>= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
inline BitBoard operator^(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result ^= rhs;
|
|
return result;
|
|
}
|
|
inline BitBoard operator|(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result |= rhs;
|
|
return result;
|
|
}
|
|
inline BitBoard operator&(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result &= rhs;
|
|
return result;
|
|
}
|
|
inline BitBoard operator<<(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result <<= rhs;
|
|
return result;
|
|
}
|
|
inline BitBoard operator>>(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result >>= rhs;
|
|
return result;
|
|
}
|
|
|
|
// Arithmetic operators
|
|
constexpr BitBoard &BitBoard::operator+=(const BitBoard &rhs) {
|
|
mBoard += rhs.mBoard;
|
|
return *this;
|
|
}
|
|
constexpr BitBoard &BitBoard::operator-=(const BitBoard &rhs) {
|
|
mBoard -= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
constexpr BitBoard &BitBoard::operator%=(const BitBoard &rhs) {
|
|
mBoard %= rhs.mBoard;
|
|
return *this;
|
|
}
|
|
inline BitBoard operator+(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result += rhs;
|
|
return result;
|
|
}
|
|
inline BitBoard operator-(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result -= rhs;
|
|
return result;
|
|
}
|
|
inline BitBoard operator%(const BitBoard &lhs, const BitBoard &rhs) {
|
|
BitBoard result(lhs);
|
|
result %= rhs;
|
|
return result;
|
|
}
|
|
|
|
constexpr void BitBoard::set(const unsigned i) {
|
|
mBoard |= (1ULL << i);
|
|
}
|
|
constexpr void BitBoard::clear(const unsigned i) {
|
|
mBoard &= ~(1ULL << i);
|
|
}
|
|
inline BitBoard BitBoard::fromIndex(const unsigned i) {
|
|
return 1ULL << i;
|
|
}
|
|
|
|
inline BitBoard BitBoard::north() const {
|
|
return (mBoard << 8);
|
|
}
|
|
inline BitBoard BitBoard::northEast() const {
|
|
return (mBoard << 9) & ~AFile;
|
|
}
|
|
inline BitBoard BitBoard::northWest() const {
|
|
return (mBoard << 7) & ~HFile;
|
|
}
|
|
inline BitBoard BitBoard::west() const {
|
|
return (mBoard >> 1) & ~HFile;
|
|
}
|
|
inline BitBoard BitBoard::east() const {
|
|
return (mBoard << 1) & ~AFile;
|
|
}
|
|
inline BitBoard BitBoard::south() const {
|
|
return (mBoard >> 8);
|
|
}
|
|
inline BitBoard BitBoard::southEast() const {
|
|
return (mBoard >> 7) & ~AFile;
|
|
}
|
|
inline BitBoard BitBoard::southWest() const {
|
|
return (mBoard >> 9) & ~HFile;
|
|
}
|
|
|
|
inline unsigned BitBoard::lsb() const {
|
|
return __builtin_ctzll(mBoard);
|
|
}
|
|
inline unsigned BitBoard::pop() {
|
|
unsigned i = lsb();
|
|
mBoard &= mBoard - 1;
|
|
|
|
return i;
|
|
}
|
|
|
|
constexpr int BitBoard::count() const {
|
|
return __builtin_popcountll(mBoard);
|
|
}
|
|
|
|
|
|
#endif //CHESS_ENGINE_BITBOARD_HPP
|