-
Notifications
You must be signed in to change notification settings - Fork 14
Bitboard
The chess package implements a bitboard representation for chess positions using unsigned 64-bit integers. A bitboard is a space-efficient data structure that represents the chess board as a series of bits, where each bit corresponds to a specific square on the board.
The bitboard uses a 64-bit integer where each bit represents one square on the chess board. The bits are ordered from most significant (A1) to least significant (H8):
8 | 56 57 58 59 60 61 62 63
7 | 48 49 50 51 52 53 54 55
6 | 40 41 42 43 44 45 46 47
5 | 32 33 34 35 36 37 38 39
4 | 24 25 26 27 28 29 30 31
3 | 16 17 18 19 20 21 22 23
2 | 08 09 10 11 12 13 14 15
1 | 00 01 02 03 04 05 06 07
-------------------------
A B C D E F G H
The numbers represent the bit position in the 64-bit integer. A value of 1 indicates the presence of a piece on that square, while 0 indicates an empty square.
type bitboard uint64The bitboard type is an alias for uint64 that provides chess-specific operations and methods.
func newBitboard(m map[Square]bool) bitboardCreates a new bitboard from a map of squares. The map keys are Square values, and the boolean values indicate whether each square is occupied.
Example usage:
squares := map[Square]bool{
NewSquare(FileA, Rank1): true,
NewSquare(FileE, Rank4): true,
}
bb := newBitboard(squares)func (b bitboard) Mapping() map[Square]boolConverts a bitboard back to a map representation. Returns a map where the keys are Square values and the values indicate whether each square is occupied.
func (b bitboard) String() stringReturns a 64-character string of 1s and 0s representing the bitboard, starting with the most significant bit (A1). Useful for debugging and string representation.
func (b bitboard) Draw() stringReturns a visual ASCII representation of the bitboard, showing the board layout with file and rank labels. Example output:
A B C D E F G H
8 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0
4 0 0 0 1 0 0 0 0
3 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
func (b bitboard) Reverse() bitboardReturns a new bitboard with the bit order reversed. This can be useful for operations that require working with the board from the opposite perspective.
func (b bitboard) Occupied(sq Square) boolChecks if a specific square is occupied (has a bit set to 1) on the bitboard.
Bitboards support efficient operations using bitwise operators:
- Set a bit:
bb |= (1 << position) - Clear a bit:
bb &= ^(1 << position) - Test a bit:
bb & (1 << position) != 0 - Count occupied squares:
bits.OnesCount64(uint64(bb))
Bitboards are particularly efficient for generating legal moves. Common operations include:
- Shifting for pawn moves:
bb << 8(white pawn forward) - Diagonal moves: combinations of
<<and>>with file masks - Pre-calculated attack tables for knights and kings
- Bitboards allow for very fast move generation and position evaluation due to efficient CPU operations on 64-bit integers.
- Multiple bitboards can be used together to represent different piece types or colors.
- Bitwise operations can be used to quickly determine:
- Piece attacks
- Board control
- Piece mobility
- Square control
// Create a bitboard with pieces on A1 and E4
squares := map[Square]bool{
NewSquare(FileA, Rank1): true,
NewSquare(FileE, Rank4): true,
}
bb := newBitboard(squares)
fmt.Println(bb.Draw())sq := NewSquare(FileE, Rank4)
if bb.Occupied(sq) {
fmt.Printf("Square %v is occupied\n", sq)
}// Combining two bitboards using OR
whitePieces := bitboard(0x000000000000FF00) // Second rank pawns
blackPieces := bitboard(0x00FF000000000000) // Seventh rank pawns
allPieces := whitePieces | blackPieces