Skip to content
Corentin Giaufer Saubert edited this page Dec 27, 2024 · 1 revision

Chess Board Representation

Overview

The chess package uses a sophisticated board representation that combines bitboards with convenient lookup maps for optimal performance and ease of use. Each board state is represented by the Board struct, which maintains separate bitboards for each piece type and color, along with additional convenience bitboards for quick position analysis.

Board Structure

The Board struct maintains the following state:

type Board struct {
    // Piece bitboards
    bbWhiteKing   bitboard
    bbWhiteQueen  bitboard
    bbWhiteRook   bitboard
    bbWhiteBishop bitboard
    bbWhiteKnight bitboard
    bbWhitePawn   bitboard
    bbBlackKing   bitboard
    bbBlackQueen  bitboard
    bbBlackRook   bitboard
    bbBlackBishop bitboard
    bbBlackKnight bitboard
    bbBlackPawn   bitboard
    
    // Convenience bitboards
    whiteSqs      bitboard
    blackSqs      bitboard
    emptySqs      bitboard
    
    // King square trackers
    whiteKingSq   Square
    blackKingSq   Square
}

Piece Bitboards

Each piece type (King, Queen, Rook, Bishop, Knight, Pawn) for each color (White, Black) has its own dedicated bitboard. This allows for:

  • Quick piece location lookups
  • Efficient move generation
  • Fast position evaluation

Convenience Bitboards

The board maintains three additional bitboards for optimization:

  • whiteSqs: All squares occupied by white pieces
  • blackSqs: All squares occupied by black pieces
  • emptySqs: All empty squares

These convenience bitboards are automatically updated whenever the board state changes and provide O(1) lookup for:

  • Square occupation checks
  • Color-based position analysis
  • Move validation

King Square Trackers

The position of both kings is tracked separately using whiteKingSq and blackKingSq. This provides:

  • Instant king location lookup
  • Efficient check detection
  • Quick castling validation

Board Operations

Creation

// Create a new board from a square-piece mapping
func NewBoard(m map[Square]Piece) *Board

Example:

squares := map[Square]Piece{
    NewSquare(FileE, Rank1): WhiteKing,
    NewSquare(FileE, Rank8): BlackKing,
}
board := NewBoard(squares)

State Query

// Get current board state as a square-piece mapping
func (b *Board) SquareMap() map[Square]Piece

// Get piece at specific square
func (b *Board) Piece(sq Square) Piece

// Check if square is occupied
func (b *Board) isOccupied(sq Square) bool

Board Manipulation

The board supports several transformation operations:

// Rotate board 90 degrees clockwise
func (b *Board) Rotate() *Board

// Flip board vertically or horizontally
func (b *Board) Flip(fd FlipDirection) *Board

// Transpose board over A8-H1 diagonal
func (b *Board) Transpose() *Board

Move Application

The board state is updated through the update method, which handles:

  • Basic piece moves
  • Captures
  • Special moves:
    • En passant captures
    • Castling
    • Pawn promotions

Serialization

The board supports multiple serialization formats:

// FEN string representation
func (b *Board) String() string
func (b *Board) MarshalText() ([]byte, error)
func (b *Board) UnmarshalText(text []byte) error

// Binary representation
func (b *Board) MarshalBinary() ([]byte, error)
func (b *Board) UnmarshalBinary(data []byte) error

Position Analysis

Material Evaluation

The board can analyze positions for sufficient material:

func (b *Board) hasSufficientMaterial() bool

This method checks for:

  • Presence of major pieces (Queen, Rook)
  • Pawn existence
  • Minor piece combinations
  • Same-colored bishop scenarios

Visual Debugging

The board provides visualization methods for debugging:

// ASCII representation of the board
func (b *Board) Draw() string

Example output:

 A B C D E F G H
8 r n b q k b n r
7 p p p p p p p p
6 - - - - - - - -
5 - - - - - - - -
4 - - - - - - - -
3 - - - - - - - -
2 P P P P P P P P
1 R N B Q K B N R

Performance Considerations

  1. Bitboard Operations: Most operations use bitwise operations, which are extremely fast on modern CPUs.
  2. Memory Usage: Each board instance uses 12 bitboards (64 bits each) plus convenience fields.
  3. Copy Operations: The copy() method performs a shallow copy, suitable for move generation and position analysis.
  4. Cached Information: King positions and convenience bitboards are maintained to avoid recalculation.

Thread Safety

The board itself is not thread-safe and should be copied when used across goroutines.

Known Limitations

  1. The board representation does not store:
    • Move history
    • Castling rights
    • En passant target squares
  2. These must be tracked separately by the game state manager.

Best Practices

  1. Use SquareMap() for iteration over pieces
  2. Use bitboard operations for move generation
  3. Use convenience bitboards for quick occupation checks
  4. Copy the board when exploring multiple variations
  5. Use Draw() for debugging complex positions

Clone this wiki locally