Compare commits

...

2 Commits

Author SHA1 Message Date
84afaa2ada Move methods from Board to BitBoard 2022-12-22 01:35:37 +01:00
a1d4dadaa2 [BitBoard] improvements 2022-12-22 00:52:35 +01:00
4 changed files with 197 additions and 232 deletions

View File

@@ -1,102 +1,9 @@
#include <iostream>
#include "BitBoard.h" #include "BitBoard.h"
//BitBoard::BitBoard() {
// mBoard = 0;
//}
BitBoard::BitBoard(uint64_t v) { BitBoard::BitBoard(uint64_t v) {
mBoard = v; mBoard = v;
} }
BitBoard::operator bool() const {
return mBoard != 0;
}
BitBoard::operator unsigned long long() const {
return mBoard;
}
bool BitBoard::operator==(const BitBoard &rhs) const {
return mBoard == rhs.mBoard;
}
bool BitBoard::operator!=(const BitBoard &rhs) const {
return !(rhs == *this);
}
bool BitBoard::operator<(const BitBoard &rhs) const {
return mBoard < rhs.mBoard;
}
bool BitBoard::operator>(const BitBoard &rhs) const {
return rhs < *this;
}
bool BitBoard::operator<=(const BitBoard &rhs) const {
return !(rhs < *this);
}
bool BitBoard::operator>=(const BitBoard &rhs) const {
return !(*this < rhs);
}
BitBoard &BitBoard::operator&=(const BitBoard &rhs) {
mBoard &= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator|=(const BitBoard &rhs) {
mBoard |= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator^=(const BitBoard &rhs) {
mBoard ^= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator<<=(const BitBoard &rhs) {
mBoard <<= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator>>=(const BitBoard &rhs) {
mBoard >>= rhs.mBoard;
return *this;
}
BitBoard BitBoard::operator~() {
BitBoard result(*this);
result.mBoard = ~mBoard;
return result;
}
BitBoard &BitBoard::operator+=(const BitBoard &rhs) {
mBoard += rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator-=(const BitBoard &rhs) {
mBoard -= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator*=(const BitBoard &rhs) {
mBoard *= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator/=(const BitBoard &rhs) {
mBoard /= rhs.mBoard;
return *this;
}
BitBoard &BitBoard::operator%=(const BitBoard &rhs) {
mBoard %= rhs.mBoard;
return *this;
}
std::ostream &operator<<(std::ostream &os, const BitBoard &board) { std::ostream &operator<<(std::ostream &os, const BitBoard &board) {
// For debugging only, performance isn't important // For debugging only, performance isn't important
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {
@@ -117,64 +24,10 @@ std::ostream &operator<<(std::ostream &os, const BitBoard &board) {
return os; return os;
} }
bool BitBoard::operator!() const {
return !mBoard;
}
bool BitBoard::operator&&(const BitBoard &rhs) const { BitBoard BitBoard::getRank(int r) {
return mBoard && rhs.mBoard; return (genShift(1ULL, (r + 1) * 8) - 1) & genShift(~1ULL, r * 8 - 1);
} }
BitBoard BitBoard::genShift(BitBoard x, const int s) {
bool BitBoard::operator||(const BitBoard &rhs) const { return (s < 0) ? (x >> -s) : (s > 63) ? x : (x << s);
return mBoard || rhs.mBoard;
}
BitBoard::operator void *() const {
return (void *) mBoard;
}
BitBoard operator&(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result &= rhs;
return result;
}
BitBoard operator|(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result |= rhs;
return result;
}
BitBoard operator^(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result ^= rhs;
return result;
}
BitBoard operator<<(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result <<= rhs;
return result;
}
BitBoard operator>>(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result >>= rhs;
return result;
}
BitBoard operator-(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result -= rhs;
return result;
}
BitBoard operator*(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result *= rhs;
return result;
}
BitBoard operator%(const BitBoard &lhs, const BitBoard &rhs) {
BitBoard result(lhs);
result %= rhs;
return result;
} }

View File

@@ -3,62 +3,206 @@
#include <cstdint> #include <cstdint>
#include <ostream> #include <ostream>
#include "CastlingRights.hpp"
class BitBoard final { class BitBoard final {
public: public:
using U64 = uint64_t; using U64 = uint64_t;
BitBoard(uint64_t v = 0); BitBoard(U64 v = 0);
// explicit operator uint64_t() const; explicit constexpr operator bool() const {
explicit operator bool() const; return mBoard != 0;
explicit operator unsigned long long() const; }
operator void*() const; explicit constexpr operator unsigned long long() const {
return mBoard;
}
operator void *() const {
return (void *) mBoard;
}
bool operator==(const BitBoard &rhs) const; // Relational operators
bool operator!=(const BitBoard &rhs) const; constexpr bool operator==(const BitBoard &rhs) const;
bool operator<(const BitBoard &rhs) const; constexpr bool operator!=(const BitBoard &rhs) const;
bool operator>(const BitBoard &rhs) const; constexpr bool operator<(const BitBoard &rhs) const;
bool operator<=(const BitBoard &rhs) const; constexpr bool operator>(const BitBoard &rhs) const;
bool operator>=(const BitBoard &rhs) const; constexpr bool operator<=(const BitBoard &rhs) const;
constexpr bool operator>=(const BitBoard &rhs) const;
// bitset operations // Logical operators
BitBoard &operator&=(const BitBoard &rhs); constexpr bool operator!() const;
BitBoard &operator|=(const BitBoard &rhs); constexpr bool operator&&(const BitBoard &rhs) const;
BitBoard &operator^=(const BitBoard &rhs); constexpr bool operator||(const BitBoard &rhs) const;
BitBoard &operator<<=(const BitBoard &rhs);
BitBoard &operator>>=(const BitBoard &rhs);
BitBoard operator~();
bool operator!() const; // Bitwise operators
bool operator&&(const BitBoard &rhs) const; constexpr BitBoard &operator&=(const BitBoard &rhs);
bool operator||(const BitBoard &rhs) const; 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);
BitBoard &operator+=(const BitBoard &rhs); // Arithmetic operators
BitBoard &operator-=(const BitBoard &rhs); constexpr BitBoard &operator+=(const BitBoard &rhs);
BitBoard &operator*=(const BitBoard &rhs); constexpr BitBoard &operator-=(const BitBoard &rhs);
BitBoard &operator/=(const BitBoard &rhs); constexpr BitBoard &operator%=(const BitBoard &rhs);
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); friend std::ostream &operator<<(std::ostream &os, const BitBoard &board);
// friend bool operator&&(const bool &lhs, const BitBoard &rhs);
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: private:
U64 mBoard = {}; 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);
}
BitBoard operator^(const BitBoard &lhs, const BitBoard &rhs); // Logical operators
BitBoard operator|(const BitBoard &lhs, const BitBoard &rhs); constexpr bool BitBoard::operator!() const {
BitBoard operator&(const BitBoard &lhs, const BitBoard &rhs); return !mBoard;
BitBoard operator<<(const BitBoard &lhs, const BitBoard &rhs); }
BitBoard operator>>(const BitBoard &lhs, const BitBoard &rhs); constexpr bool BitBoard::operator&&(const BitBoard &rhs) const {
BitBoard operator+(const BitBoard &lhs, const BitBoard &rhs); return mBoard && rhs.mBoard;
BitBoard operator-(const BitBoard &lhs, const BitBoard &rhs); }
//BitBoard operator*(const BitBoard &lhs, const BitBoard &rhs); constexpr bool BitBoard::operator||(const BitBoard &rhs) const {
//BitBoard operator/(const BitBoard &lhs, const BitBoard &rhs); return mBoard || rhs.mBoard;
BitBoard operator%(const BitBoard &lhs, const BitBoard &rhs); }
// 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::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 #endif //CHESS_ENGINE_BITBOARD_HPP

View File

@@ -16,16 +16,16 @@ void Board::setPiece(const Square &square, const Piece::Optional &piece) {
auto index = square.index(); auto index = square.index();
for (auto &bb : mPieceBBs) { for (auto &bb : mPieceBBs) {
clearIndex(bb, index); bb.clear(index);
} }
setIndex(mPieceBBs[toIndex(piece->type())], index); mPieceBBs[toIndex(piece->type())].set(index);
setIndex(mPieceBBs[toIndex(piece->color())], index); mPieceBBs[toIndex(piece->color())].set(index);
setIndex(mOccupiedBB, index); mOccupiedBB.set(index);
} }
Piece::Optional Board::piece(const Square &square) const { Piece::Optional Board::piece(const Square &square) const {
BitBoard mask = indexToBitBoard(square.index()); BitBoard mask = BitBoard::fromIndex(square.index());
if (!(mOccupiedBB & mask)) { if (!(mOccupiedBB & mask)) {
return std::nullopt; return std::nullopt;
} }
@@ -63,8 +63,8 @@ Square::Optional Board::enPassantSquare() const {
void Board::makeMove(const Move &move) { void Board::makeMove(const Move &move) {
BitBoard fromBB = indexToBitBoard(move.from().index()); BitBoard fromBB = BitBoard::fromIndex(move.from().index());
BitBoard toBB = indexToBitBoard(move.to().index()); BitBoard toBB = BitBoard::fromIndex(move.to().index());
BitBoard changeBB = fromBB ^ toBB; BitBoard changeBB = fromBB ^ toBB;
// If Piece is captured // If Piece is captured
@@ -119,7 +119,7 @@ void Board::makeMove(const Move &move) {
} }
void Board::handleEnPassant(const Move &move, const Piece &movedPiece) { void Board::handleEnPassant(const Move &move, const Piece &movedPiece) {
if (movedPiece.type() == PieceType::Pawn && mEPS.has_value() && move.from().file() != move.to().file()) { 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); auto capturedPiece = Piece(!mTurn, PieceType::Pawn);
mPieceBBs[toIndex(capturedPiece.color())] ^= epBB; 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 fromR = move.from().rank();
auto toR = move.to().rank(); auto toR = move.to().rank();
auto diff = abs(static_cast<int>(fromR) - static_cast<int>(toR)); auto diff = abs(static_cast<int>(fromR) - static_cast<int>(toR));
if (diff == 2 && (mPieceBBs[toIndex(PieceType::Pawn)] & (bb << 1 | bb >> 1) & getRankBB(static_cast<int>(toR)))) { if (diff == 2 && (mPieceBBs[toIndex(PieceType::Pawn)] & (bb.left(1) | bb.right(1)) & BitBoard::getRank(static_cast<int>(toR)))) {
mEPS = Square::fromCoordinates(move.to().file(), std::max(fromR, toR) - 1); mEPS = Square::fromCoordinates(move.to().file(), std::max(fromR, toR) - 1);
return; return;
} }
@@ -193,10 +193,10 @@ bool Board::isMoveCastling(const BitBoard &from, const BitBoard &to, const Piece
} }
if (piece.color() == PieceColor::White) { 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) { std::ostream &operator<<(std::ostream &os, const Board &board) {

View File

@@ -67,26 +67,6 @@ private:
// Check if the move is castling without checking the rights or validity. // 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 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) { static inline int toIndex(PieceType t) {
return static_cast<int>(t); return static_cast<int>(t);
} }
@@ -114,18 +94,6 @@ private:
return static_cast<PieceType>(0); return static_cast<PieceType>(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<unsigned long long>(b));
}
void handlePawnDoubleAdvance(const Move &move, BitBoard bb, const Piece &movedPiece); void handlePawnDoubleAdvance(const Move &move, BitBoard bb, const Piece &movedPiece);
void handleEnPassant(const Move &move, const Piece &movedPiece); void handleEnPassant(const Move &move, const Piece &movedPiece);
}; };