chess

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2025 License: MIT Imports: 10 Imported by: 0

README

Chess Package

Overview

The chess package implements the complete set of standard chess rules on top of the core board representation. It handles all the chess-specific logic while delegating the basic board operations to the underlying board implementation.

This package is designed with flexibility in mind, allowing you to:

  1. Use it as a complete chess rules engine
  2. Extend it to create chess variants
  3. Replace components to customize behavior

Architecture

The Chess struct wraps a board implementation and adds all the chess-specific rules and logic:

  • Turn management (white/black)
  • Move legality validation
  • Special move handling (castling, en passant, promotion)
  • Check and checkmate detection
  • Game state tracking (halfmove clock, fullmove counter)
  • FEN notation support

By default, it uses the standard pkg.Board implementation, but it can work with any board that satisfies the Board interface, making it ideal for creating chess variants.

API

The Chess package exports the following key functions:

func New(options ...Option) (*Chess, error)
func (c *Chess) FEN() string
func (c *Chess) AvailableMoves() []string
func (c *Chess) MakeMove(move string) error
func (c *Chess) UnmakeMove()
func (c *Chess) IsCheck() bool
func (c *Chess) IsCheckmate() bool
func (c *Chess) IsStalemate() bool
func (c *Chess) LoadPosition(fen string) error
func (c *Chess) Clone() *Chess
Core Functions
  • New(options ...Option): Creates a new chess game with the specified options. Without options, it creates a standard starting position.

  • FEN() string: Returns the current position in Forsyth-Edwards Notation (FEN).

  • AvailableMoves() []string: Returns all possible legal moves in UCI format.

  • MakeMove(move string) error: Validates and executes a move in UCI format (e.g., "e2e4"). Returns an error if the move is illegal.

  • UnmakeMove(): Reverts the last move made, restoring the previous position.

  • IsCheck() bool: Returns whether the current player's king is in check. If the position is checkmate or stalemate, it returns false.

  • IsCheckmate() bool: Returns whether the current player's king is in checkmate.

  • IsStalemate() bool: Returns whether the game is in stalemate.

  • LoadPosition(fen string) error: Sets up the board according to the provided FEN string.

  • Clone() *Chess: Returns a copy of the chess game.

Creating a Chess Game

Basic Usage
// Create a new chess game with the standard starting position
game, err := chess.New()
if err != nil {
    // Handle error
}

// Get all legal moves for the current player
moves := game.AvailableMoves()

// Make a move
err = game.MakeMove("e2e4")
if err != nil {
    // Handle error
}
Custom Starting Position
// Create a game from a specific FEN position
game, err := chess.New(chess.WithFEN("r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3"))

Options

The New function accepts options to customize the chess game:

  • WithBoard(board Board): Uses a custom board implementation. This should be the first option if used.

  • WithFEN(fen string): Sets up the board using the provided FEN string.

  • WithParallelism(parallelism int): Sets the number of parallel workers to use for move generation. The default is twice the number of CPU cores.

Board Interface

Any board implementation used with the Chess package must satisfy this interface:

type Board interface {
    LoadPosition(string) error
    Square(c pkg.Coordinate) (int8, error)
    AvailableMoves(turn int8, enPassantSquare, castlePossibilities string) ([]string, error)
    Width() int
}

Creating Chess Variants

To create a chess variant:

  1. Implement a custom board that satisfies the Board interface
  2. Pass it to the Chess constructor using the WithBoard option
  3. Extend the Chess struct if needed to add variant-specific rules

Example for a custom variant:

// Create a custom board implementation
customBoard := myvariant.NewCustomBoard()

// Create a chess game using the custom board
game, err := chess.New(chess.WithBoard(customBoard))

This modular approach allows you to focus only on the aspects that differ in your variant while leveraging the existing chess logic for everything else.

Performance Optimization

Parallel Move Calculation

GoChess uses a parallel processing approach to calculate legal moves, which significantly improves performance on multi-core systems:

  • Automatic Parallelism: By default, GoChess uses twice as many workers as available CPU cores to maximize performance.
  • Efficient Cloning: The system implements a Cloner interface that allows creating independent copies of the board for each worker, avoiding race conditions.
  • Customizable Configuration: The level of parallelism can be adjusted using the WithParallelism option, allowing optimization based on the execution environment.
// Create a game with a specific level of parallelism
game, err := chess.New(chess.WithParallelism(4))
Memory Optimizations
  • Capacity Preallocation: Slices for storing moves are preallocated with specific capacities based on the piece type.
  • Efficient Representation: Pieces are represented using bits, allowing fast operations and minimal memory usage.
Environment Adaptation
  • Containerized Environments: In environments with limited resources, it is recommended to manually adjust the level of parallelism. If you are using a containerized environment, you should set the parallelism manually to avoid issues with the number of available CPU cores.
  • Sequential Mode: For applications that do not require high performance, it can be configured to perform calculations sequentially.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AlgebraicToCoordinate

func AlgebraicToCoordinate(s string) (gochess.Coordinate, error)

AlgebraicToCoordinate returns a new Coordinate from text notation. For example, "a1" would return (0, 0). If the text notation is invalid, an empty Coordinate is returned.

func CoordinateToAlgebraic

func CoordinateToAlgebraic(c gochess.Coordinate) string

CoordinateToAlgebraic returns a new algebraic notation from a Coordinate. For example, (0, 0) would return "a1". If the Coordinate is out of bounds, an empty string is returned.

func UCI

func UCI(origin, target gochess.Coordinate, piece ...int8) string

UCI returns the UCI notation of a move.

It receives the origin and target coordinates of the move. For example, if the origin is (0, 0) and the target is (0, 1), it would return "a1a2".

If the move is a promotion, it receives the piece to promote to. If it receives more than one piece, it returns the first one.

Types

type Board

type Board interface {
	// SetSquare sets a piece in a square.
	SetSquare(c gochess.Coordinate, p int8) error
	// Square returns the piece in a square.
	Square(c gochess.Coordinate) (int8, error)
	// Width returns the width of the board.
	Width() int
}

Board represents a chess board.

type Chess

type Chess struct {
	// contains filtered or unexported fields
}

Chess represents a Chess game.

func New

func New(opts ...Option) (*Chess, error)

New creates a new chess game.

The chess.AvailableMoves method will use a pool of workers to maximize performance on the moves calculation. By default, the number of workers is twice the number of available CPUs. If you are running on a container environment or you want to use the sequential version, you should set this value manually using the WithParallelism option. The pool of workers will be used only if the board implements the Cloner interface. If you are using a custom Board with the WithBoard option, you should implement the Cloner interface to take advantage of the parallelism.

func (*Chess) AvailableMoves

func (c *Chess) AvailableMoves() []string

AvailableMoves returns the available legal moves for the current turn.

It always returns a non nil slice. It could be empty if the position is checkmate or stalemate.

func (*Chess) FEN

func (c *Chess) FEN() string

FEN returns the FEN string of the current position.

If any of the kings is not in the board, the function returns an empty string.

func (*Chess) IsCheck

func (c *Chess) IsCheck() bool

IsCheck returns if the current turn is in check.

func (*Chess) IsCheckmate added in v1.2.0

func (c *Chess) IsCheckmate() bool

IsCheckmate returns if the current turn is in checkmate.

func (*Chess) IsStalemate added in v1.2.0

func (c *Chess) IsStalemate() bool

IsStalemate returns if the current turn is in stalemate.

func (*Chess) LoadPosition

func (c *Chess) LoadPosition(FEN string) error

LoadPosition loads a board from a FEN string.

The function will read the entire FEN string and will return an error if the FEN string is invalid.

The board and properties will not be modified if the FEN string is invalid.

func (*Chess) MakeMove

func (c *Chess) MakeMove(move string) error

MakeMove checks if the move is legal and makes it. It returns an error if the move is not legal.

func (*Chess) Square

func (c *Chess) Square(square string) (string, error)

Square returns the piece in a square. The square is represented by an algebraic notation.

If the square is not valid, the function returns an error.

func (*Chess) UnmakeMove

func (c *Chess) UnmakeMove()

UnmakeMove unmake the last move.

It searches for the last move in the history and unmake it. If there are no moves in the history, the function does nothing.

type Cloner added in v1.2.0

type Cloner interface {
	// Clone returns a clone of the object.
	Clone() Board
}

Cloner is a generic interface for objects that can be cloned.

type Option

type Option func(*Chess) error

Option is a function that configures a chess.

func WithBoard

func WithBoard(b Board) Option

WithBoard sets the board of the chess. If the board is nil, it returns an error. If you want to use this option, it must be the first one.

func WithFEN

func WithFEN(FEN string) Option

WithFEN sets the FEN of the chess. If the FEN is invalid, it returns an error. If you try to set the FEN before the board, it will set the default board.

func WithParallelism added in v1.2.0

func WithParallelism(n int) Option

WithParallelism sets the number of workers to use for the moves calculation. If the number of workers is less or equal to 1, the Chess will use the sequential version without throwing goroutines.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL