#include #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; BitBoard diag1 = bishops; BitBoard diag2 = bishops; empty ^= bishops; for (int i = 0; i < 7; 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; BitBoard diag1 = rooks; BitBoard diag2 = rooks; empty ^= rooks; for (int i = 0; i < 7; i++) { result |= (diag1 | diag2); diag1 = (diag1.north() | diag1.south()) & empty; diag2 = (diag2.east() | diag2.west()) & empty; } return (result | diag1.north() | diag1.south() | diag2.east() | diag2.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; }