#ifndef CHESS_ENGINE_BITBOARD_HPP #define CHESS_ENGINE_BITBOARD_HPP #include #include #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 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 kingAttacks(BitBoard kings); 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(); private: U64 mBoard = {}; }; // 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; } #endif //CHESS_ENGINE_BITBOARD_HPP