132 lines
3.8 KiB
C++
132 lines
3.8 KiB
C++
#include "BitBoard.hpp"
|
|
|
|
BitBoard::BitBoard(uint64_t v) {
|
|
mBoard = v;
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &os, const BitBoard &board) {
|
|
// For debugging only, performance isn't important
|
|
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.
|
|
// Print piece, otherwise '.';
|
|
if (board.mBoard & (1ULL << (rank + j))) {
|
|
os << 1;
|
|
} else {
|
|
os << '.';
|
|
}
|
|
|
|
os << ' ';
|
|
}
|
|
os << '\n';
|
|
}
|
|
|
|
return os;
|
|
}
|
|
|
|
BitBoard BitBoard::northFill() const {
|
|
BitBoard result(mBoard);
|
|
result |= (result << 8);
|
|
result |= (result << 16);
|
|
result |= (result << 32);
|
|
return (result << 8);
|
|
}
|
|
|
|
BitBoard BitBoard::southFill() const {
|
|
BitBoard result(mBoard);
|
|
result |= (result >> 8);
|
|
result |= (result >> 16);
|
|
result |= (result >> 32);
|
|
return result;
|
|
}
|
|
|
|
BitBoard BitBoard::fileFill() const {
|
|
return northFill() | southFill();
|
|
}
|
|
|
|
BitBoard BitBoard::kingMoves(const BitBoard kings) {
|
|
BitBoard result = kings.east() | kings.west() | kings;
|
|
result |= (result.north() | result.south());
|
|
result ^= kings;
|
|
|
|
return result;
|
|
}
|
|
|
|
BitBoard BitBoard::castlingMoves(BitBoard kings, BitBoard rooks, BitBoard empty) {
|
|
kings |= (kings.east() | kings.west()) & empty;
|
|
kings |= (kings.east() | kings.west()) & empty;
|
|
kings |= kings.west() & empty;
|
|
rooks |= (rooks.east() | rooks.west()) & empty;
|
|
rooks |= (rooks.east() | rooks.west()) & empty;
|
|
rooks |= (rooks.east()) & empty;
|
|
|
|
return kings & rooks & CastlingSquares;
|
|
}
|
|
|
|
BitBoard BitBoard::bishopAttacks(BitBoard bishops, BitBoard empty) {
|
|
BitBoard result = 0;
|
|
empty ^= bishops;
|
|
|
|
BitBoard diag1 = (bishops.northWest() | bishops.southEast() | bishops) & empty;
|
|
BitBoard diag2 = (bishops.northEast() | bishops.southWest() | bishops) & empty;
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
result |= (diag1 | diag2);
|
|
diag1 = (diag1.northWest() | diag1.southEast()) & empty;
|
|
diag2 = (diag2.northEast() | diag2.southWest()) & empty;
|
|
}
|
|
|
|
return (result | diag1.northWest() | diag1.southEast() | diag2.northEast() | diag2.southWest()) & ~bishops;
|
|
}
|
|
|
|
BitBoard BitBoard::rookAttacks(BitBoard rooks, BitBoard empty) {
|
|
BitBoard result = 0;
|
|
empty ^= rooks;
|
|
|
|
BitBoard dir1 = (rooks.north() | rooks.south() | rooks) & empty;
|
|
BitBoard dir2 = (rooks.east() | rooks.west() | rooks) & empty;
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
result |= (dir1 | dir2);
|
|
dir1 = (dir1.north() | dir1.south()) & empty;
|
|
dir2 = (dir2.east() | dir2.west()) & empty;
|
|
}
|
|
|
|
return (result | dir1.north() | dir1.south() | dir2.east() | dir2.west()) & ~rooks;
|
|
}
|
|
|
|
BitBoard BitBoard::queenAttacks(BitBoard queens, BitBoard empty) {
|
|
return rookAttacks(queens, empty) | bishopAttacks(queens, empty);
|
|
}
|
|
|
|
BitBoard BitBoard::knightMoves(BitBoard knights) {
|
|
BitBoard east, west, result;
|
|
|
|
east = knights.east();
|
|
west = knights.west();
|
|
result = (east | west) << 16;
|
|
result |= (east | west) >> 16;
|
|
east = east.east();
|
|
west = west.west();
|
|
result |= (east | west) << 8;
|
|
result |= (east | west) >> 8;
|
|
|
|
return result;
|
|
}
|
|
|
|
BitBoard BitBoard::pawnNorthAttacks(BitBoard pawns, BitBoard targets) {
|
|
return (pawns.northEast() | pawns.northWest()) & targets;
|
|
}
|
|
BitBoard BitBoard::pawnNorthMoves(BitBoard pawns, BitBoard empty) {
|
|
pawns = pawns.north() & empty;
|
|
return (pawns | (pawns.north() & Rank4)) & empty;
|
|
}
|
|
|
|
BitBoard BitBoard::pawnSouthAttacks(BitBoard pawns, BitBoard targets) {
|
|
return (pawns.southEast() | pawns.southWest()) & targets;
|
|
}
|
|
BitBoard BitBoard::pawnSouthMoves(BitBoard pawns, BitBoard empty) {
|
|
pawns = pawns.south() & empty;
|
|
return (pawns | (pawns.south() & Rank5)) & empty;
|
|
} |