136 lines
3.7 KiB
C++
136 lines
3.7 KiB
C++
#ifndef CHESS_ENGINE_BOARD_HPP
|
|
#define CHESS_ENGINE_BOARD_HPP
|
|
|
|
#include "Piece.hpp"
|
|
#include "Square.hpp"
|
|
#include "Move.hpp"
|
|
#include "CastlingRights.hpp"
|
|
#include "BitBoard.h"
|
|
|
|
#include <optional>
|
|
#include <iosfwd>
|
|
#include <vector>
|
|
|
|
#define BB_NUM 8 // 6 pieces, 2 colors
|
|
|
|
enum class BoardIndex {
|
|
|
|
};
|
|
|
|
class Board {
|
|
public:
|
|
|
|
using Optional = std::optional<Board>;
|
|
using MoveVec = std::vector<Move>;
|
|
|
|
Board();
|
|
|
|
void setPiece(const Square &square, const Piece::Optional &piece);
|
|
Piece::Optional piece(const Square &square) const;
|
|
void setTurn(PieceColor turn);
|
|
PieceColor turn() const;
|
|
void setCastlingRights(CastlingRights cr);
|
|
CastlingRights castlingRights() const;
|
|
void setEnPassantSquare(const Square::Optional &square);
|
|
Square::Optional enPassantSquare() const;
|
|
|
|
void makeMove(const Move &move);
|
|
|
|
void pseudoLegalMoves(MoveVec &moves) const;
|
|
void pseudoLegalMovesFrom(const Square &from, MoveVec &moves) const;
|
|
|
|
private:
|
|
|
|
BitBoard mPieceBBs[BB_NUM] = {};
|
|
BitBoard mOccupiedBB = 0;
|
|
|
|
PieceColor mTurn = PieceColor::White;
|
|
CastlingRights mCR = CastlingRights::None;
|
|
std::optional<Square> mEPS;
|
|
|
|
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,
|
|
WhiteCastlingRank = (1ULL << A2) - 1,
|
|
BlackCastlingRank = (~1ULL << H7),
|
|
CastlingRanks = WhiteCastlingRank | BlackCastlingRank,
|
|
CastlingSquares = (WhiteCastlingRank | BlackCastlingRank) & (CFile | GFile),
|
|
};
|
|
|
|
void handleCastlingRights(const Piece &piece, const BitBoard &bb);
|
|
// 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<int>(t);
|
|
}
|
|
static inline int toIndex(PieceColor c) {
|
|
return static_cast<int>(c);
|
|
}
|
|
|
|
inline PieceColor pieceColor(const BitBoard &mask) const {
|
|
auto color = PieceColor::White;
|
|
if (!(mPieceBBs[static_cast<unsigned>(color)] & mask)) {
|
|
color = !color;
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
inline PieceType pieceType(const BitBoard &mask) const {
|
|
for (int i = 2; i < BB_NUM; i++) {
|
|
if (mPieceBBs[i] & mask) {
|
|
return static_cast<PieceType>(i);
|
|
}
|
|
}
|
|
|
|
// Should not happen
|
|
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 handleEnPassant(const Move &move, const Piece &movedPiece);
|
|
};
|
|
|
|
std::ostream &operator<<(std::ostream &os, const Board &board);
|
|
|
|
#endif
|