Implement Search

This commit is contained in:
2022-12-23 18:34:34 +01:00
parent bcf4d66c49
commit 87adca7e66
15 changed files with 337 additions and 66 deletions

View File

@@ -1,3 +1,4 @@
#include <iostream>
#include "MoveGenerator.hpp"
#include "Board.hpp"
#include "BoardState.hpp"
@@ -28,9 +29,9 @@ void MoveGenerator::generatePawnMoves(const BoardState &bs, const Square &from,
bool isPromotion = movesBB & (Rank1 | Rank8);
if (isPromotion) {
generateMovesWithPromotion(from, movesBB, moves);
generateMovesWithPromotion(bs, from, movesBB, moves);
} else {
generateMoves(from, movesBB, moves);
generateMoves(bs, from, movesBB, moves);
}
}
@@ -38,19 +39,29 @@ void MoveGenerator::generateBishopMoves(const BoardState &bs, const Square &from
auto fromBB = BitBoard::fromIndex(from.index());
auto movesBB = BitBoard::bishopAttacks(fromBB, ~bs.occupiedBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
generateMoves(from, movesBB, moves);
generateMoves(bs, from, movesBB, moves);
}
void MoveGenerator::generateMoves(const Square &from, BitBoard movesBB, MoveVec &moves) {
void MoveGenerator::generateMoves(const BoardState &bs, const Square &from, BitBoard movesBB, MoveVec &moves) {
auto fromBB = BitBoard::fromIndex(from.index());
while (movesBB) {
auto to = Square(movesBB.pop());
moves.emplace_back(from, to, std::nullopt);
if (isCheck(bs, fromBB, to)) {
continue;
}
moves.emplace_back(from, to);
}
}
void MoveGenerator::generateMovesWithPromotion(const Square &from, BitBoard movesBB, MoveVec &moves) {
void MoveGenerator::generateMovesWithPromotion(const BoardState &bs, const Square &from, BitBoard movesBB, MoveVec &moves) {
auto fromBB = BitBoard::fromIndex(from.index());
while (movesBB) {
auto to = Square(movesBB.pop());
if (isCheck(bs, fromBB, to)) {
continue;
}
for (const auto &kItem : Piece::PromotionTypes) {
moves.emplace_back(from, to, static_cast<PieceType>(kItem));
}
@@ -74,7 +85,7 @@ void MoveGenerator::generateKingMoves(const BoardState &bs, const Square &from,
if (checkCR != CastlingRights::None) {
// Generate attacked squares
BitBoard target = CastlingRanks | bs.occupiedBB;
auto attacked = generateAttackedSquares(bs, target, !bs.turn);
auto attacked = generateAttackedSquares(bs, ~target, !bs.turn);
movesBB |= BitBoard::castlingMoves(fromBB & ~attacked,
(*bs.pieceBBs)[Board::toIndex(PieceType::Rook)],
@@ -89,28 +100,28 @@ void MoveGenerator::generateKingMoves(const BoardState &bs, const Square &from,
}
}
generateMoves(from, movesBB, moves);
generateMoves(bs, 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);
generateMoves(bs, 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);
generateMoves(bs, from, movesBB, moves);
}
void MoveGenerator::generateKnightMoves(const BoardState &bs, const Square &from, MoveVec &moves) {
auto fromBB = BitBoard::fromIndex(from.index());
auto movesBB = BitBoard::knightMoves(fromBB) & ~(*bs.pieceBBs)[Board::toIndex(bs.turn)];
generateMoves(from, movesBB, moves);
generateMoves(bs, from, movesBB, moves);
}
BitBoard MoveGenerator::generateAttackedSquares(const BoardState &bs, BitBoard target, PieceColor opColor) {
@@ -125,7 +136,7 @@ BitBoard MoveGenerator::generateAttackedSquares(const BoardState &bs, BitBoard t
}
// knights
attacked |= BitBoard::knightMoves((*bs.pieceBBs)[Board::toIndex(PieceType::Knight)] & opponentBB) & target;
attacked |= BitBoard::knightMoves((*bs.pieceBBs)[Board::toIndex(PieceType::Knight)] & opponentBB) & ~target;
// Bishop
attacked |= BitBoard::bishopAttacks((*bs.pieceBBs)[Board::toIndex(PieceType::Bishop)] & opponentBB, target);
@@ -137,7 +148,20 @@ BitBoard MoveGenerator::generateAttackedSquares(const BoardState &bs, BitBoard t
attacked |= BitBoard::queenAttacks((*bs.pieceBBs)[Board::toIndex(PieceType::Queen)] & opponentBB, target);
// King
attacked |= BitBoard::kingMoves((*bs.pieceBBs)[Board::toIndex(PieceType::Queen)] & opponentBB) & target;
attacked |= BitBoard::kingMoves((*bs.pieceBBs)[Board::toIndex(PieceType::Queen)] & opponentBB) & ~target;
return attacked;
}
inline bool MoveGenerator::isCheck(const BoardState &bs, const BitBoard &fromBB, const Square &to) {
auto kingBB = (*bs.pieceBBs)[Board::toIndex(bs.turn)] & (*bs.pieceBBs)[Board::toIndex(PieceType::King)];
auto toBB = BitBoard::fromIndex(to.index());
auto changeBB = (fromBB ^ toBB);
auto target = bs.occupiedBB ^ changeBB;
auto attacked = generateAttackedSquares(bs, ~target, !bs.turn);
if (kingBB & fromBB) {
kingBB ^= changeBB;
}
return attacked & kingBB;
}