136 lines
5.1 KiB
C++
136 lines
5.1 KiB
C++
#include <iostream>
|
|
#include "MoveGenerator.hpp"
|
|
#include "Board.hpp"
|
|
#include "BoardState.hpp"
|
|
|
|
void MoveGenerator::generatePawnMoves(const BoardState &bs, const Square &from, MoveVec &moves) {
|
|
|
|
BitBoard targets = 0;
|
|
if (bs.eps.has_value()) {
|
|
targets |= BitBoard::fromIndex(bs.eps.value().index());
|
|
}
|
|
|
|
generatePawnMoves(bs, from, targets, moves);
|
|
}
|
|
|
|
void MoveGenerator::generatePawnMoves(const BoardState &bs, const Square &from, BitBoard targets, MoveVec &moves) {
|
|
|
|
auto fromBB = BitBoard::fromIndex(from.index());
|
|
targets |= (*bs.pieceBBs)[Board::toIndex(!bs.turn)];
|
|
|
|
BitBoard movesBB;
|
|
if (bs.turn == PieceColor::White) {
|
|
movesBB = BitBoard::pawnNorthAttacks(fromBB, targets) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
movesBB |= BitBoard::pawnNorthMoves(fromBB, ~bs.occupiedBB);
|
|
} else {
|
|
movesBB = BitBoard::pawnSouthAttacks(fromBB, targets) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
movesBB |= BitBoard::pawnSouthMoves(fromBB, ~bs.occupiedBB);
|
|
}
|
|
|
|
bool isPromotion = movesBB & (Rank1 | Rank8);
|
|
if (isPromotion) {
|
|
generateMovesWithPromotion(from, movesBB, moves);
|
|
} else {
|
|
generateMoves(from, movesBB, moves);
|
|
}
|
|
}
|
|
|
|
void MoveGenerator::generateBishopMoves(const BoardState &bs, const Square &from, MoveVec &moves) {
|
|
auto fromBB = BitBoard::fromIndex(from.index());
|
|
auto movesBB = BitBoard::bishopAttacks(fromBB, ~bs.occupiedBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
|
|
generateMoves(from, movesBB, moves);
|
|
}
|
|
|
|
void MoveGenerator::generateMoves(const Square &from, BitBoard movesBB, MoveVec &moves) {
|
|
while (movesBB) {
|
|
auto to = Square(movesBB.pop());
|
|
moves.emplace_back(from, to, std::nullopt);
|
|
}
|
|
}
|
|
|
|
void MoveGenerator::generateMovesWithPromotion(const Square &from, BitBoard movesBB, MoveVec &moves) {
|
|
while (movesBB) {
|
|
auto to = Square(movesBB.pop());
|
|
for (const auto &kItem : Piece::PromotionTypes) {
|
|
moves.emplace_back(from, to, static_cast<PieceType>(kItem));
|
|
}
|
|
}
|
|
}
|
|
void MoveGenerator::generateKingMoves(const BoardState &bs, const Square &from, MoveGenerator::MoveVec &moves) {
|
|
auto fromBB = BitBoard::fromIndex(from.index());
|
|
auto movesBB = BitBoard::kingAttacks(fromBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
|
|
if ((bs.cr & CastlingRights::All) != CastlingRights::None) {
|
|
|
|
auto checkCR = CastlingRights::White;
|
|
auto castlingRank = WhiteCastlingRank;
|
|
if (bs.turn == PieceColor::Black) {
|
|
checkCR = CastlingRights::Black;
|
|
castlingRank = BlackCastlingRank;
|
|
}
|
|
|
|
checkCR &= bs.cr;
|
|
|
|
if (checkCR != CastlingRights::None) {
|
|
// Generate attacked squares
|
|
// auto opponentBB = (*bs.pieceBBs)[Board::toIndex(!color)];
|
|
// BitBoard target = CastlingRanks | bs.occupiedBB;
|
|
// // pawns
|
|
// BitBoard attacked = 0;
|
|
// if (!color == PieceColor::White) {
|
|
// attacked |= BitBoard::pawnNorthAttacks((*bs.pieceBBs)[Board::toIndex(PieceType::Pawn)] & opponentBB, target);
|
|
// } else {
|
|
// attacked |= BitBoard::pawnSouthAttacks((*bs.pieceBBs)[Board::toIndex(PieceType::Pawn)] & opponentBB, target);
|
|
// }
|
|
|
|
movesBB |= BitBoard::castlingMoves(fromBB, (*bs.pieceBBs)[Board::toIndex(PieceType::Rook)], ~bs.occupiedBB)
|
|
& castlingRank;// & ~attacked;
|
|
|
|
if ((checkCR & CastlingRights::KingSide) == CastlingRights::None) {
|
|
movesBB &= ~GFile;
|
|
}
|
|
if ((checkCR & CastlingRights::QueenSide) == CastlingRights::None) {
|
|
movesBB &= ~CFile;
|
|
}
|
|
}
|
|
}
|
|
|
|
generateMoves(from, movesBB, moves);
|
|
}
|
|
|
|
void MoveGenerator::generateRookMoves(const BoardState &bs, const Square &from, MoveVec &moves) {
|
|
auto fromBB = BitBoard::fromIndex(from.index());
|
|
auto movesBB = BitBoard::rookAttacks(fromBB, ~bs.occupiedBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
|
|
generateMoves(from, movesBB, moves);
|
|
}
|
|
|
|
void MoveGenerator::generateQueenMoves(const BoardState &bs, const Square &from, MoveVec &moves) {
|
|
auto fromBB = BitBoard::fromIndex(from.index());
|
|
auto movesBB = BitBoard::queenAttacks(fromBB, ~bs.occupiedBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
|
|
generateMoves(from, movesBB, moves);
|
|
}
|
|
|
|
void MoveGenerator::generateKnightMoves(const BoardState &bs, const Square &from, MoveVec &moves) {
|
|
|
|
auto fromBB = BitBoard::fromIndex(from.index());
|
|
auto movesBB = BitBoard::knightAttacks(fromBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
|
|
generateMoves(from, movesBB, moves);
|
|
}
|
|
|
|
//BitBoard MoveGenerator::generateAttackedSquares(const BoardState &bs, BitBoard target, PieceColor opColor) const {
|
|
// auto opponentBB = (*bs.pieceBBs)[Board::toIndex(opColor)];
|
|
//
|
|
// BitBoard attacked = 0;
|
|
//
|
|
// // pawns
|
|
// if (opColor == PieceColor::White) {
|
|
// attacked |= BitBoard::pawnNorthAttacks((*bs.pieceBBs)[Board::toIndex(PieceType::Pawn)] & opponentBB, target);
|
|
// } else {
|
|
// attacked |= BitBoard::pawnSouthAttacks((*bs.pieceBBs)[Board::toIndex(PieceType::Pawn)] & opponentBB, target);
|
|
// }
|
|
//
|
|
//}
|