diff --git a/BitBoard.cpp b/BitBoard.cpp index 30c7d73..0feb37d 100644 --- a/BitBoard.cpp +++ b/BitBoard.cpp @@ -23,4 +23,11 @@ std::ostream &operator<<(std::ostream &os, const BitBoard &board) { } return os; -} \ No newline at end of file +} + +BitBoard BitBoard::getRank(int r) { + return (genShift(1ULL, (r + 1) * 8) - 1) & genShift(~1ULL, r * 8 - 1); +} +BitBoard BitBoard::genShift(BitBoard x, const int s) { + return (s < 0) ? (x >> -s) : (s > 63) ? x : (x << s); +} diff --git a/BitBoard.h b/BitBoard.h index d208e43..d245764 100644 --- a/BitBoard.h +++ b/BitBoard.h @@ -8,101 +8,129 @@ class BitBoard final { public: using U64 = uint64_t; - BitBoard(uint64_t v = 0); + BitBoard(U64 v = 0); explicit constexpr operator bool() const { return mBoard != 0; } - explicit constexpr operator unsigned long long() const { return mBoard; } - operator void *() const { return (void *) mBoard; } // Relational operators - constexpr bool operator==(const BitBoard &rhs) const { - return mBoard == rhs.mBoard; - } - constexpr bool operator!=(const BitBoard &rhs) const { - return !(rhs == *this); - } - constexpr bool operator<(const BitBoard &rhs) const { - return mBoard < rhs.mBoard; - } - constexpr bool operator>(const BitBoard &rhs) const { - return rhs < *this; - } - constexpr bool operator<=(const BitBoard &rhs) const { - return !(rhs < *this); - } - constexpr bool operator>=(const BitBoard &rhs) const { - return !(*this < rhs); - } + 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 { - return !mBoard; - } - constexpr bool operator&&(const BitBoard &rhs) const { - return mBoard && rhs.mBoard; - } - constexpr bool operator||(const BitBoard &rhs) const { - return mBoard || rhs.mBoard; - } + constexpr bool operator!() const; + constexpr bool operator&&(const BitBoard &rhs) const; + constexpr bool operator||(const BitBoard &rhs) const; - // Compound Bitwise assignment operators - constexpr BitBoard &operator&=(const BitBoard &rhs) { - mBoard &= rhs.mBoard; - return *this; - } - constexpr BitBoard &operator|=(const BitBoard &rhs) { - mBoard |= rhs.mBoard; - return *this; - } - constexpr BitBoard &operator^=(const BitBoard &rhs) { - mBoard ^= rhs.mBoard; - return *this; - } - constexpr BitBoard &operator<<=(const BitBoard &rhs) { - mBoard <<= rhs.mBoard; - return *this; - } - constexpr BitBoard &operator>>=(const BitBoard &rhs) { - mBoard >>= rhs.mBoard; - return *this; - } - BitBoard operator~() { + // 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); - // Compound Arithmetic assignment operators - constexpr BitBoard &operator+=(const BitBoard &rhs) { - mBoard += rhs.mBoard; - return *this; - } - constexpr BitBoard &operator-=(const BitBoard &rhs) { - mBoard -= rhs.mBoard; - return *this; - } - constexpr BitBoard &operator%=(const BitBoard &rhs) { - mBoard %= rhs.mBoard; - return *this; - } + // 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 left(unsigned i) const; + BitBoard right(unsigned i) const; + static BitBoard fromIndex(unsigned i); + + static BitBoard genShift(BitBoard x, int s); + static BitBoard getRank(int r); + + // Returns the number of trailing 0-bits in b. + // WARN: Check for 0! + int lsb() const; + 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; @@ -130,6 +158,18 @@ inline BitBoard operator>>(const BitBoard &lhs, const BitBoard &rhs) { } // 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; @@ -146,4 +186,23 @@ inline BitBoard operator%(const BitBoard &lhs, const BitBoard &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::left(const unsigned int i) const { + return (mBoard >> i); +} +inline BitBoard BitBoard::right(const unsigned int i) const { + return (mBoard << i); +} +inline int BitBoard::lsb() const { + return __builtin_ctzll(mBoard); +} + #endif //CHESS_ENGINE_BITBOARD_HPP diff --git a/Board.cpp b/Board.cpp index a44c858..ff7369f 100644 --- a/Board.cpp +++ b/Board.cpp @@ -16,16 +16,16 @@ void Board::setPiece(const Square &square, const Piece::Optional &piece) { auto index = square.index(); for (auto &bb : mPieceBBs) { - clearIndex(bb, index); + bb.clear(index); } - setIndex(mPieceBBs[toIndex(piece->type())], index); - setIndex(mPieceBBs[toIndex(piece->color())], index); - setIndex(mOccupiedBB, index); + mPieceBBs[toIndex(piece->type())].set(index); + mPieceBBs[toIndex(piece->color())].set(index); + mOccupiedBB.set(index); } Piece::Optional Board::piece(const Square &square) const { - BitBoard mask = indexToBitBoard(square.index()); + BitBoard mask = BitBoard::fromIndex(square.index()); if (!(mOccupiedBB & mask)) { return std::nullopt; } @@ -63,8 +63,8 @@ Square::Optional Board::enPassantSquare() const { void Board::makeMove(const Move &move) { - BitBoard fromBB = indexToBitBoard(move.from().index()); - BitBoard toBB = indexToBitBoard(move.to().index()); + BitBoard fromBB = BitBoard::fromIndex(move.from().index()); + BitBoard toBB = BitBoard::fromIndex(move.to().index()); BitBoard changeBB = fromBB ^ toBB; // If Piece is captured @@ -119,7 +119,7 @@ void Board::makeMove(const Move &move) { } void Board::handleEnPassant(const Move &move, const Piece &movedPiece) { if (movedPiece.type() == PieceType::Pawn && mEPS.has_value() && move.from().file() != move.to().file()) { - auto epBB = indexToBitBoard(Square::fromCoordinates(move.to().file(), move.from().rank())->index()); + auto epBB = BitBoard::fromIndex(Square::fromCoordinates(move.to().file(), move.from().rank())->index()); auto capturedPiece = Piece(!mTurn, PieceType::Pawn); mPieceBBs[toIndex(capturedPiece.color())] ^= epBB; @@ -133,7 +133,7 @@ void Board::handlePawnDoubleAdvance(const Move &move, BitBoard bb, const Piece & auto fromR = move.from().rank(); auto toR = move.to().rank(); auto diff = abs(static_cast(fromR) - static_cast(toR)); - if (diff == 2 && (mPieceBBs[toIndex(PieceType::Pawn)] & (bb << 1 | bb >> 1) & getRankBB(static_cast(toR)))) { + if (diff == 2 && (mPieceBBs[toIndex(PieceType::Pawn)] & (bb.left(1) | bb.right(1)) & BitBoard::getRank(static_cast(toR)))) { mEPS = Square::fromCoordinates(move.to().file(), std::max(fromR, toR) - 1); return; } @@ -193,10 +193,10 @@ bool Board::isMoveCastling(const BitBoard &from, const BitBoard &to, const Piece } if (piece.color() == PieceColor::White) { - return (from & indexToBitBoard(E1)); + return (from & BitBoard::fromIndex(E1)); } - return from & indexToBitBoard(E8); + return from & BitBoard::fromIndex(E8); } std::ostream &operator<<(std::ostream &os, const Board &board) { diff --git a/Board.hpp b/Board.hpp index 791747d..9462616 100644 --- a/Board.hpp +++ b/Board.hpp @@ -67,26 +67,6 @@ private: // Check if the move is castling without checking the rights or validity. static bool isMoveCastling(const BitBoard &from, const BitBoard &to, const Piece &piece); - static inline void clearIndex(BitBoard &b, const unsigned i) { - b &= ~(1ULL << i); - } - - static inline void setIndex(BitBoard &b, const unsigned i) { - b |= 1ULL << i; - } - - static inline BitBoard indexToBitBoard(const unsigned i) { - return (1ULL << i); - } - - static inline BitBoard genShift(BitBoard x, const int s) { - return (s < 0) ? (x >> -s) : (s > 63) ? x : (x << s); - } - - static inline BitBoard getRankBB(int r) { - return (genShift(1ULL, (r + 1) * 8) - 1) & genShift(~1ULL, r * 8 - 1); - } - static inline int toIndex(PieceType t) { return static_cast(t); } @@ -114,18 +94,6 @@ private: return static_cast(0); } - inline void applyMask(const BitBoard &mask) { - for (auto &item : mPieceBBs) { - item ^= mask; - } - } - - // Returns the number of trailing 0-bits in b. - // WARN: Check for 0! - static inline int getLSB(const BitBoard b) { - return __builtin_ctzll(static_cast(b)); - } - void handlePawnDoubleAdvance(const Move &move, BitBoard bb, const Piece &movedPiece); void handleEnPassant(const Move &move, const Piece &movedPiece); };