[Board] Refactor and implement makeMove
This commit is contained in:
151
Board.cpp
151
Board.cpp
@@ -10,26 +10,28 @@ Board::Board() {
|
||||
}
|
||||
|
||||
void Board::setPiece(const Square &square, const Piece::Optional &piece) {
|
||||
if (!piece.has_value())
|
||||
return;
|
||||
|
||||
auto index = square.index();
|
||||
for (auto &item : mPieceBBs) {
|
||||
clearIndex(item, index);
|
||||
for (auto &bb : mPieceBBs) {
|
||||
clearIndex(bb, index);
|
||||
}
|
||||
|
||||
setIndex(mPieceBBs[piece->typeVal() + piece->colorVal()], index);
|
||||
setIndex(mPieceBBs[toIndex(piece->type())], index);
|
||||
setIndex(mPieceBBs[toIndex(piece->color())], index);
|
||||
setIndex(mOccupiedBB, index);
|
||||
}
|
||||
|
||||
Piece::Optional Board::piece(const Square &square) const {
|
||||
int i = 0;
|
||||
BitBoard mask = indexToBitBoard(square.index());
|
||||
for (const auto &kPieceBb : mPieceBBs) {
|
||||
if (kPieceBb & mask) {
|
||||
return Piece::fromValue(i);
|
||||
}
|
||||
|
||||
i++;
|
||||
if (!(mOccupiedBB & mask)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::nullopt;
|
||||
|
||||
auto c = pieceColor(mask);
|
||||
auto t = pieceType(mask);
|
||||
return Piece(c, t);
|
||||
}
|
||||
|
||||
void Board::setTurn(PieceColor turn) {
|
||||
@@ -41,11 +43,11 @@ PieceColor Board::turn() const {
|
||||
}
|
||||
|
||||
void Board::setCastlingRights(CastlingRights cr) {
|
||||
mCr = cr;
|
||||
mCR = cr;
|
||||
}
|
||||
|
||||
CastlingRights Board::castlingRights() const {
|
||||
return mCr;
|
||||
return mCR;
|
||||
}
|
||||
|
||||
void Board::setEnPassantSquare(const Square::Optional &square) {
|
||||
@@ -57,7 +59,56 @@ Square::Optional Board::enPassantSquare() const {
|
||||
}
|
||||
|
||||
void Board::makeMove(const Move &move) {
|
||||
(void) move;
|
||||
|
||||
BitBoard fromBB = indexToBitBoard(move.from().index());
|
||||
BitBoard toBB = indexToBitBoard(move.to().index());
|
||||
BitBoard changeBB = fromBB ^ toBB;
|
||||
|
||||
// If Piece is captured
|
||||
if (mOccupiedBB & toBB) {
|
||||
auto capturedPiece = Piece(!mTurn, pieceType(toBB));
|
||||
mPieceBBs[toIndex(capturedPiece.color())] ^= toBB;
|
||||
mPieceBBs[toIndex(capturedPiece.type())] ^= toBB;
|
||||
mOccupiedBB ^= fromBB;
|
||||
|
||||
if (toBB & CastlingRanks) { // Check castling rights
|
||||
handleCastlingRights(capturedPiece, toBB);
|
||||
}
|
||||
} else {
|
||||
mOccupiedBB ^= changeBB; // update occupied bitboard
|
||||
}
|
||||
|
||||
auto movedPiece = Piece(mTurn, pieceType(fromBB));
|
||||
mPieceBBs[toIndex(movedPiece.color())] ^= changeBB; // update color bitboard
|
||||
|
||||
// TODO verify if we should check if piece == Pawn
|
||||
if (move.promotion().has_value()) {
|
||||
mPieceBBs[toIndex(movedPiece.type())] ^= fromBB; // Remove old piece
|
||||
mPieceBBs[toIndex(move.promotion().value())] ^= toBB; // Set new piece
|
||||
} else {
|
||||
mPieceBBs[toIndex(movedPiece.type())] ^= changeBB; // remove and set piece bitboard
|
||||
}
|
||||
|
||||
if ((fromBB & CastlingRanks)) {
|
||||
handleCastlingRights(movedPiece, fromBB);
|
||||
|
||||
if (isMoveCastling(fromBB, toBB, movedPiece)) {
|
||||
BitBoard rookBB;
|
||||
if (toBB & GFile) { // Kingside
|
||||
rookBB = (fromBB << 3) | (fromBB << 1);
|
||||
} else {
|
||||
rookBB = (fromBB >> 4) | (fromBB >> 1);
|
||||
}
|
||||
|
||||
mPieceBBs[toIndex(PieceType::Rook)] ^= rookBB;
|
||||
mPieceBBs[toIndex(movedPiece.color())] ^= rookBB;
|
||||
mOccupiedBB ^= rookBB;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// change turn
|
||||
mTurn = !mTurn;
|
||||
}
|
||||
|
||||
void Board::pseudoLegalMoves(MoveVec &moves) const {
|
||||
@@ -69,26 +120,72 @@ void Board::pseudoLegalMovesFrom(const Square &from,
|
||||
(void) from;
|
||||
(void) moves;
|
||||
}
|
||||
void Board::handleCastlingRights(const Piece &piece, const BitBoard &bb) {
|
||||
if (piece.type() != PieceType::King && piece.type() != PieceType::Rook) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto crColor = CastlingRights::White;
|
||||
auto crKingside = CastlingRights::WhiteKingside;
|
||||
auto crQueenside = CastlingRights::WhiteQueenside;
|
||||
|
||||
if (piece.color() == PieceColor::Black) {
|
||||
crColor = CastlingRights::Black;
|
||||
crKingside = CastlingRights::BlackKingside;
|
||||
crQueenside = CastlingRights::BlackQueenside;
|
||||
}
|
||||
|
||||
if ((mCR & crColor) == CastlingRights::None) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (piece.type() == PieceType::King) {
|
||||
mCR &= ~crColor;
|
||||
return;
|
||||
}
|
||||
|
||||
if (piece.type() == PieceType::Rook) {
|
||||
if (bb & (HFile & CastlingRanks)) { // Kingside
|
||||
mCR &= ~crKingside;
|
||||
} else if (bb & (AFile & CastlingRanks)) { // Queenside
|
||||
mCR &= ~crQueenside;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Board::isMoveCastling(const BitBoard &from, const BitBoard &to, const Piece &piece) {
|
||||
if (piece.type() != PieceType::King)
|
||||
return false;
|
||||
|
||||
if (!(to & CastlingSquares)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (piece.color() == PieceColor::White) {
|
||||
return (from & indexToBitBoard(E1));
|
||||
}
|
||||
|
||||
return (from & indexToBitBoard(E8));
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Board &board) {
|
||||
// For debugging only, performance isn't important
|
||||
for (int i = 63; i >= 0; i--) {
|
||||
// Get the piece for this index. Assume it exists.
|
||||
auto piece = board.piece(Square::fromIndex(i).value());
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
int rank = i * 8;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
// Get the piece for this index. Assume it exists.
|
||||
auto piece = board.piece(Square::fromIndex(rank + j).value());
|
||||
|
||||
// Print piece, otherwise '.';
|
||||
if (piece.has_value()) {
|
||||
os << piece.value();
|
||||
} else {
|
||||
os << '.';
|
||||
}
|
||||
// Print piece, otherwise '.';
|
||||
if (piece.has_value()) {
|
||||
os << piece.value();
|
||||
} else {
|
||||
os << '.';
|
||||
}
|
||||
|
||||
// If a file is done, output newline
|
||||
if (i % 8 == 0) {
|
||||
os << '\n';
|
||||
} else {
|
||||
os << ' ';
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
return os;
|
||||
|
Reference in New Issue
Block a user