Bitboard representation in chess engines
Bitboard representation
Definition
A bitboard is a way of representing the chessboard using 64-bit integers, where each bit corresponds to one square. A bit set to 1 means “present/true” (for example, a piece occupies that square or that square is attacked), and a bit set to 0 means “absent/false.” Most engines maintain multiple bitboards at once—typically one for each piece type and color (12 in total), plus aggregate boards like “all white,” “all black,” and “occupied.”
Common mapping: bit 0 = a1, bit 1 = b1, …, bit 7 = h1, bit 8 = a2, …, up to bit 63 = h8. With this mapping:
- White pawns at the start: 0x000000000000FF00
- White knights at b1 and g1: 0x0000000000000042
- Black pawns at the start: 0x00FF000000000000
- File A mask (all a-file squares): 0x0101010101010101
- Rank 1 mask: 0x00000000000000FF
Why it’s used
Bitboards enable extremely fast move generation, attack detection, and position evaluation by leveraging native CPU bitwise operations (AND, OR, XOR, shifts) and hardware instructions like popcount and bit scan. This speed translates directly into deeper searches per second—vital for strong computer chess.
How it works in practice
Core operations
- Occupancy and colors:
- occupied = whitePieces OR blackPieces
- empty = NOT occupied
- pins/checks often found by intersecting attack masks with king squares
- Counting and locating:
- popcount(bitboard) gives the number of set bits (e.g., number of pawns)
- bit scan forward/backward finds the least/most significant 1-bit (to iterate pieces)
- Non-sliding attacks (precomputed or computed on the fly):
- Knight and king attacks can be a precomputed table indexed by square → attack bitboard
- Pawn moves/attacks via shifts and masks, e.g. white single push: (whitePawns << 8) AND empty
- Sliding attacks (bishops/rooks/queens):
- Magic bitboards or similar techniques map (occupancy along rays, from a square) → attack set via a fast table lookup
- Older methods include rotated bitboards; both avoid scanning square-by-square at runtime
Typical engine layout
- 12 piece-type bitboards: WP, WN, WB, WR, WQ, WK, and BP, BN, BB, BR, BQ, BK
- Aggregates: whiteAll, blackAll, occupied, empty
- Helper masks: files (A–H), ranks (1–8), diagonals/anti-diagonals, promotion ranks, center squares, light/dark squares
Examples
Starting position masks
Using the a1-as-least-significant-bit mapping:
- White pieces (ranks 1 and 2): 0x000000000000FFFF
- Black pieces (ranks 7 and 8): 0xFFFF000000000000
- White pawns: 0x000000000000FF00; Black pawns: 0x00FF000000000000
- White knights: 0x0000000000000042; Black knights: 0x4200000000000000
Single move update: 1. e4
After 1. e4, the white pawn moves from e2 (bit 12) to e4 (bit 28):
- Start: 0x000000000000FF00
- Remove e2: subtract 0x0000000000001000 → 0x000000000000EF00
- Add e4: OR 0x0000000010000000 → whitePawnBitboard = 0x000000001000EF00
Knight attack mask: knight on d4
From d4, a knight attacks c2, e2, b3, f3, b5, f5, c6, e6. Engines get this instantly using a precomputed table or by shifts with file-edge masks.
Sliding example in a famous opening
Consider the Ruy Lopez: 1. e4 e5 2. Nf3 Nc6 3. Bb5. The light-squared bishop now sits on b5, putting pressure on the knight at c6 and indirectly on the e5 pawn through the pin motif.
White bishops here are on c1 and b5. With a1 as the least significant bit, c1 is bit 2 and b5 is bit 33, so the white-bishop bitboard is 0x0000000200000004.
Preview the position:
A sliding-attack generator would compute bishop rays from b5 along a4–c6–d7–e8, stopping at the first blocker. Internally that’s a quick table lookup using magic bitboards indexed by the occupancy along those diagonals.
Strategic and historical significance
Why bitboards mattered
Bitboards allowed engines to dramatically accelerate move generation and attack detection, enabling deeper searches within time controls. This was especially impactful as 64-bit CPUs became ubiquitous, matching the 64 squares perfectly.
Evolution in engines
- Earlier engines often used mailbox or 0x88 representation boards; bitboards gained popularity as hardware popcount and fast table lookups became widely available.
- Techniques such as rotated bitboards (earlier) and later magic bitboards for sliding pieces improved speed and simplicity.
- Modern elite engines (e.g., Stockfish and its predecessors) rely on bitboards throughout evaluation and search.
Interesting facts and tips
- Light/dark-squares masks are simple repeating bit patterns; file and rank masks are useful for pawn structure evaluation and passed-pawn detection.
- Pawn structure features (isolated, doubled, backward pawns) can be computed with shifts and AND/OR on pawn bitboards—no loops needed.
- Legality checks (e.g., whether the king is in check after a move) reduce to fast bitwise tests: is (enemyAttacks AND kingSquare) nonzero?
- Zobrist hashing integrates cleanly with bitboards: adding/removing a piece toggles a small set of random keys.
- On 32-bit systems, engines sometimes used pairs of 32-bit integers to emulate 64-bit bitboards; today, native 64-bit operations plus POPCNT/LZCNT dominate.