chester

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Mar 25, 2026 License: MIT Imports: 11 Imported by: 0

README

Chester

Go Reference Tests codecov Go Report Card Go Version

A chess library and engine written in Go.

Library Features

  • Fast legal move generation using bitboards
  • FEN (Forsyth–Edwards Notation) parsing and serialization
  • Magic bitboard sliding piece attack lookup
  • Zobrist hashing (Polyglot-compatible)
  • Perft for move generation testing and benchmarking

Engine Features

  • Universal Chess Interface (UCI)
  • Negamax with Alpha-Beta pruning
  • Tranposition Table
  • Search time / nodes budget
  • Iterative Deepening
  • Quiescence search
  • PeSTO evaluation function
  • Opening book support (Polyglot .bin format)

Demo

Play against Chester in lichess.

Installation

go get github.com/bluescreen10/chester

Usage

As a library
import "github.com/bluescreen10/chester"

// Parse a position from FEN
pos, err := chester.ParseFEN(chester.DefaultFEN)
if err != nil {
    panic(err)
}

// Generate legal moves
var moves []chester.Move
moves, inCheck := chester.LegalMoves(moves, &pos)

// Apply a move
pos.Do(moves[0])

// Serialize back to FEN
fmt.Println(pos.FEN())

// Perft
results := chester.Perft(&pos, 6)
var nodes int
for r := range results {
    nodes += r.Count
}
fmt.Printf("nodes: %d\n", nodes)
As an engine (UCI)
go run ./cmd
position startpos
perft 6

a2a3: 4463267
b2b3: 5310358
c2c3: 5417640
d2d3: 8073082
e2e3: 9726018
f2f3: 4404141
g2g3: 5346260
h2h3: 4463070
a2a4: 5363555
b2b4: 5293555
c2c4: 5866666
d2d4: 8879566
e2e4: 9771632
f2f4: 4890429
g2g4: 5239875
h2h4: 5385554
b1a3: 4856835
b1c3: 5708064
g1f3: 5723523
g1h3: 4877234
perft 119060324 in 363.214708ms

(The above results were produced in a Macbook Pro M2)

References

Documentation

Index

Constants

View Source
const (
	Pawn = Piece(iota)
	Knight
	Bishop
	Rook
	Queen
	King
	Empty
)
View Source
const (
	// Scored used to track available Mates
	Inf       = 1_000_000_000
	MateScore = 1_000_000
)
View Source
const DefaultFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

DefaultFEN is the FEN string for the standard starting position.

Variables

This section is empty.

Functions

func EvalMaterial added in v0.2.0

func EvalMaterial(p *Position) int

eval returns a static evaluation of position p in centipawns using material count only. Positive values favour Attacking, negative values favour Defending.

Piece values:

Pawn=100  Knight=300  Bishop=300  Rook=500  Queen=900

func EvalPesto added in v0.2.0

func EvalPesto(p *Position) int

EvalPesto calculates a static evaluation of the given Position using the PeSTO (Pietro Simone's Table-only) method.

It utilizes Tapered Evaluation, which calculates separate scores for the midgame and endgame based on Piece-Square Tables (PST). These scores are then linearly interpolated based on the current game phase, determined by the remaining material on the board.

PeSTO is highly efficient as it provides sophisticated positional awareness (like king safety and pawn structure) purely through table lookups without the need for complex tactical logic.

func Perft

func Perft(p *Position, depth int) <-chan MoveCount

Perft performs a performance test (perft) from position p to the given depth and returns a channel of MoveCount values, one per legal move in p. Each value carries the root move and the total number of leaf nodes reachable from it at the given depth.

The traversal runs in a separate goroutine; the channel is closed when all root moves have been processed. Callers can sum the counts to obtain the total node count, or print them individually for move-by-move debugging against a reference engine such as Stockfish.

Depth 1 returns one MoveCount per legal move, each with Count == 1.

Example:

var total int
for mc := range chester.Perft(pos, 5) {
    fmt.Printf("%s: %d\n", mc.Move, mc.Count)
    total += mc.Count
}
fmt.Printf("total: %d\n", total)

func SearchBestMove

func SearchBestMove(p *Position, opts *SearchOptions) (chan Evaluation, context.CancelFunc)

SearchBestMove searches for the best move in position p and sends the result on the returned channel, which is closed when the search completes. Additionally a cancel func is returned to stop the search.

Types

type Bitboard

type Bitboard uint64

Bitboard is a 64-bit mask representing a set of squares. Each bit corresponds to one square using the same index as Square: bit 0 = a8, bit 63 = h1. Multiple bits may be set to represent a set of squares, such as all squares occupied by white pawns.

const (
	BB_SQ_A1 Bitboard = 1 << SQ_A1
	BB_SQ_B1 Bitboard = 1 << SQ_B1
	BB_SQ_C1 Bitboard = 1 << SQ_C1
	BB_SQ_D1 Bitboard = 1 << SQ_D1
	BB_SQ_E1 Bitboard = 1 << SQ_E1
	BB_SQ_F1 Bitboard = 1 << SQ_F1
	BB_SQ_G1 Bitboard = 1 << SQ_G1
	BB_SQ_H1 Bitboard = 1 << SQ_H1

	BB_SQ_A8 Bitboard = 1 << SQ_A8
	BB_SQ_B8 Bitboard = 1 << SQ_B8
	BB_SQ_C8 Bitboard = 1 << SQ_C8
	BB_SQ_D8 Bitboard = 1 << SQ_D8
	BB_SQ_E8 Bitboard = 1 << SQ_E8
	BB_SQ_F8 Bitboard = 1 << SQ_F8
	BB_SQ_G8 Bitboard = 1 << SQ_G8
	BB_SQ_H8 Bitboard = 1 << SQ_H8
)

Single-square Bitboard constants for the first and eighth ranks. Named BB_SQ_<file><rank>, e.g. BB_SQ_E1 has only the e1 bit set. Used as masks in castling legality checks and rights updates.

const (
	File_A Bitboard = 0x0101010101010101
	File_B Bitboard = 0x0202020202020202
	File_C Bitboard = 0x0404040404040404
	File_D Bitboard = 0x0808080808080808
	File_E Bitboard = 0x1010101010101010
	File_F Bitboard = 0x2020202020202020
	File_G Bitboard = 0x4040404040404040
	File_H Bitboard = 0x8080808080808080

	Rank_1 Bitboard = 0xFF00000000000000
	Rank_2 Bitboard = 0x00FF000000000000
	Rank_3 Bitboard = 0x0000FF0000000000
	Rank_4 Bitboard = 0x000000FF00000000
	Rank_5 Bitboard = 0x00000000FF000000
	Rank_6 Bitboard = 0x0000000000FF0000
	Rank_7 Bitboard = 0x000000000000FF00
	Rank_8 Bitboard = 0x00000000000000FF

	File_Not_A Bitboard = ^File_A
	File_Not_H Bitboard = ^File_H

	EmptyBoard Bitboard = 0
	FullBoard  Bitboard = 0xFFFFFFFFFFFFFFFF
)

func NewBitboardFromSquare

func NewBitboardFromSquare(sq Square) Bitboard

NewBitboardFromSquare returns a Bitboard with only the bit for sq set.

func (Bitboard) OnesCount

func (b Bitboard) OnesCount() int

OnesCount returns the number of set bits (population count).

func (Bitboard) PopLSB

func (b Bitboard) PopLSB() (Square, Bitboard)

PopLSB removes the least significant set bit and returns its Square index together with the modified Bitboard. Typical usage:

for bb != 0 {
    sq, bb = bb.PopLSB()
    // process sq
}

func (Bitboard) RotateLeft

func (b Bitboard) RotateLeft(offset int) Bitboard

RotateLeft rotates all 64 bits left by offset positions. Negative values rotate right. Used to shift pawn attack and push masks without branching on color: a positive offset for Black and a negative offset for White.

func (Bitboard) String

func (b Bitboard) String() string

String returns a human-readable ASCII grid of the bitboard with rank numbers and file letters. Set bits are shown as X, clear bits as spaces.

type Color

type Color uint8

Color represents which side owns a set of pieces.

const (
	White Color = iota
	Black
)

type EvalFunc added in v0.2.0

type EvalFunc func(*Position) int

EvalFunc defines the signature for a function that performs a static evaluation of a Position.

It returns a score in centipawns (100 units = 1 pawn) from the perspective of the side to move. A positive value indicates an advantage for the active player, while a negative value indicates a disadvantage.

type Evaluation

type Evaluation struct {
	// Search depth reached.
	Depth int

	// Best move in pure algebraic coordinate notation (e.g. "e2e4").
	Best Move

	// Centipawn score from the side to move perspective
	Score int
}

Evaluation holds the result of a search at a given depth.

type Magic

type Magic struct {
	Attacks []Bitboard
	Magic   Bitboard
	Mask    Bitboard
	Shift   uint8
}

type Move

type Move uint16

Move encodes a chess move in 16 bits.

15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | | | promotion | from | to | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

4 bits       6 bits          6 bits

promotion 0000 -> no promotion 0001 -> knight 0010 -> bishop 0011 -> rook 0100 -> queen

func CaptureMoves added in v0.1.0

func CaptureMoves(moves []Move, p *Position) ([]Move, bool)

CaptureMoves appends all legal **capture moves** for the active color in the position p to the moves slice and returns the updated slice. The second return value indicates whether the active king is currently in check.

Capture-only generation respects the same rules as LegalMoves:

  • Double check: only king moves are generated, but only captures (seldom relevant, usually king captures if available).
  • Single check: only captures that resolve the check or along the check ray are generated.
  • Pinned pieces can only capture along their pin ray.
  • En passant captures are included if legal and do not expose the king to check.

func LegalMoves

func LegalMoves(moves []Move, p *Position) ([]Move, bool)

LegalMoves appends all legal moves for the active color in position p to moves and returns the updated slice. The second return value reports whether the active king is currently in check.

Double check restricts generation to king moves only. A single check restricts all other pieces via moveMask. When not in check, moveMask is set to EnemiesOrEmpty and all piece generators run.

func NewMove

func NewMove(from, to Square) Move

NewMove encodes a move from from to to with no promotion.

func NewPromotionMove

func NewPromotionMove(from, to Square, promotion Piece) Move

NewPromotionMove encodes a pawn promotion move from from to to, promoting to the given piece type.

func ParseMove

func ParseMove(m string, p *Position) (Move, error)

ParseMove parses a move string in pure algebraic coordinate notation (e.g. "e2e4", "e7e8q") relative to position p. An optional fifth character specifies the promotion piece: 'n', 'b', 'r', or 'q'. Returns an error if the string is malformed or the promotion character is unrecognised.

func (Move) From

func (m Move) From() Square

From returns the origin square of the move.

func (Move) IsPromotion

func (m Move) IsPromotion() bool

IsPromotion reports whether the move encodes a pawn promotion.

func (Move) PromoPiece

func (m Move) PromoPiece() Piece

PromoPiece returns the promotion piece encoded in the move, or a zero value (Knight) if the move is not a promotion. Always check IsPromotion first.

func (Move) String

func (m Move) String() string

String returns the move in pure algebraic coordinate notation, e.g. "e2e4" or "e7e8q" for a promotion to queen.

func (Move) To

func (m Move) To() Square

To returns the destination square of the move.

type MoveCount

type MoveCount struct {
	Move  Move
	Count int
}

MoveCount pairs a root move with the number of leaf nodes reachable from it at the requested depth. It is the element type of the channel returned by Perft.

type Piece

type Piece uint8

Piece identifies the type of a chess piece. Empty is a sentinel value meaning no piece occupies a square.

type Position

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

Position holds the complete state of a chess position. It combines a bitboard representation (one Bitboard per piece type, one per color) with a mailbox for O(1) square queries and an incrementally maintained Polyglot-compatible Zobrist hash.

The zero value is not a valid position; use ParseFEN to construct one.

func ParseFEN

func ParseFEN(fen string) (*Position, error)

ParseFEN parses a FEN string and returns a pointer to the resulting Position. All six FEN fields are required: piece placement, active color, castling availability, en passant target, half-move clock, and full-move number. The Zobrist hash is computed from scratch before returning. Returns an error if the string is malformed or contains an unrecognised character.

func (*Position) Active

func (p *Position) Active() Color

Active returns the color of the side whose turn it is to move.

func (*Position) Bishops

func (p *Position) Bishops() Bitboard

Bishops returns a Bitboard of all bishops belonging to the active color.

func (*Position) BlackBishops

func (p *Position) BlackBishops() Bitboard

BlackBishops returns a Bitboard of all black bishops.

func (*Position) BlackKing

func (p *Position) BlackKing() Bitboard

BlackKing returns a Bitboard with the bit set for the black king's square.

func (*Position) BlackKnights

func (p *Position) BlackKnights() Bitboard

BlackKnights returns a Bitboard of all black knights.

func (*Position) BlackPawns

func (p *Position) BlackPawns() Bitboard

BlackPawns returns a Bitboard of all black pawns.

func (*Position) BlackPieces added in v0.1.0

func (p *Position) BlackPieces() Bitboard

func (*Position) BlackQueens

func (p *Position) BlackQueens() Bitboard

BlackQueens returns a Bitboard of all black queens.

func (*Position) BlackRooks

func (p *Position) BlackRooks() Bitboard

BlackRooks returns a Bitboard of all black rooks.

func (*Position) CanBlackCastleKingSide

func (p *Position) CanBlackCastleKingSide() bool

CanBlackCastleKingSide reports whether black retains the right to castle kingside. It does not verify that the path is clear or unattacked.

func (*Position) CanBlackCastleQueenSide

func (p *Position) CanBlackCastleQueenSide() bool

CanBlackCastleQueenSide reports whether black retains the right to castle queenside. It does not verify that the path is clear or unattacked.

func (*Position) CanWhiteCastleKingSide

func (p *Position) CanWhiteCastleKingSide() bool

CanWhiteCastleKingSide reports whether white retains the right to castle kingside. It does not verify that the path is clear or unattacked.

func (*Position) CanWhiteCastleQueenSide

func (p *Position) CanWhiteCastleQueenSide() bool

CanWhiteCastleQueenSide reports whether white retains the right to castle queenside. It does not verify that the path is clear or unattacked.

func (*Position) Do

func (p *Position) Do(m Move)

Do applies a move to the position, updating piece placement, the mailbox, castling rights, en passant state, half-move clock, full-move counter, active/inactive colors, and the Zobrist hash. The move must be legal; Do does not validate it.

func (*Position) EnPassantTarget

func (p *Position) EnPassantTarget() Square

EnPassantTarget returns the square of the pawn eligible to be captured via en passant, or SQ_NULL when en passant is unavailable.

func (*Position) Enemies

func (p *Position) Enemies() Bitboard

Enemies returns a Bitboard of all squares occupied by the inactive color.

func (*Position) EnemiesOrEmpty

func (p *Position) EnemiesOrEmpty() Bitboard

EnemiesOrEmpty returns a Bitboard of all squares that are either empty or occupied by the inactive color — i.e. valid landing squares for active-color pieces when excluding friendly captures.

func (*Position) EnemyBishops

func (p *Position) EnemyBishops() Bitboard

EnemyBishops returns a Bitboard of all bishops belonging to the inactive color.

func (*Position) EnemyKing

func (p *Position) EnemyKing() Bitboard

EnemyKing returns a Bitboard with the bit set for the inactive color's king square.

func (*Position) EnemyKnights

func (p *Position) EnemyKnights() Bitboard

EnemyKnights returns a Bitboard of all knights belonging to the inactive color.

func (*Position) EnemyPawns

func (p *Position) EnemyPawns() Bitboard

EnemyPawns returns a Bitboard of all pawns belonging to the inactive color.

func (*Position) EnemyQueens

func (p *Position) EnemyQueens() Bitboard

EnemyQueens returns a Bitboard of all queens belonging to the inactive color.

func (*Position) EnemyQueensOrBishops

func (p *Position) EnemyQueensOrBishops() Bitboard

EnemyQueensOrBishops returns a Bitboard of all enemy queens and bishops — the pieces that generate diagonal threats.

func (*Position) EnemyQueensOrRooks

func (p *Position) EnemyQueensOrRooks() Bitboard

EnemyQueensOrRooks returns a Bitboard of all enemy queens and rooks — the pieces that generate straight (rank/file) threats.

func (*Position) EnemyRooks

func (p *Position) EnemyRooks() Bitboard

EnemyRooks returns a Bitboard of all rooks belonging to the inactive color.

func (*Position) FEN

func (p *Position) FEN() string

FEN returns the FEN string representation of the position.

func (*Position) FullMoves

func (p *Position) FullMoves() uint16

FullMoves returns the full-move counter. It starts at 1 and is incremented after Black's move, matching FEN semantics.

func (*Position) Get

func (p *Position) Get(sq Square) Piece

Get returns the piece occupying sq, or Empty if the square is unoccupied.

func (*Position) HalfMoves

func (p *Position) HalfMoves() uint8

HalfMoves returns the half-move clock used for the fifty-move rule. It resets to zero on any pawn move or capture.

func (*Position) Hash

func (p *Position) Hash() uint64

Hash returns the Polyglot-compatible Zobrist hash of the position. The hash is maintained incrementally by Do and will always match computeHash for a correctly constructed position.

func (*Position) Inactive

func (p *Position) Inactive() Color

Inactive returns the color of the side that is waiting to move.

func (*Position) King

func (p *Position) King() Bitboard

King returns a Bitboard with the bit set for the active color's king square.

func (*Position) Knights

func (p *Position) Knights() Bitboard

Knights returns a Bitboard of all knights belonging to the active color.

func (*Position) Occupied

func (p *Position) Occupied() Bitboard

Occupied returns a Bitboard with a bit set for every square occupied by either color.

func (*Position) Pawns

func (p *Position) Pawns() Bitboard

Pawns returns a Bitboard of all pawns belonging to the active color.

func (*Position) Queens

func (p *Position) Queens() Bitboard

Queens returns a Bitboard of all queens belonging to the active color.

func (*Position) Rooks

func (p *Position) Rooks() Bitboard

Rooks returns a Bitboard of all rooks belonging to the active color.

func (*Position) String

func (p *Position) String() string

String returns a human-readable ASCII board diagram with rank numbers and file letters. White pieces are uppercase, black pieces are lowercase.

func (*Position) WhiteBishops

func (p *Position) WhiteBishops() Bitboard

WhiteBishops returns a Bitboard of all white bishops.

func (*Position) WhiteKing

func (p *Position) WhiteKing() Bitboard

WhiteKing returns a Bitboard with the bit set for the white king's square.

func (*Position) WhiteKnights

func (p *Position) WhiteKnights() Bitboard

WhiteKnights returns a Bitboard of all white knights.

func (*Position) WhitePawns

func (p *Position) WhitePawns() Bitboard

WhitePawns returns a Bitboard of all white pawns.

func (*Position) WhitePieces added in v0.1.0

func (p *Position) WhitePieces() Bitboard

func (*Position) WhiteQueens

func (p *Position) WhiteQueens() Bitboard

WhiteQueens returns a Bitboard of all white queens.

func (*Position) WhiteRooks

func (p *Position) WhiteRooks() Bitboard

WhiteRooks returns a Bitboard of all white rooks.

type SearchOptions added in v0.2.0

type SearchOptions struct {
	// MaxTime is the maximum duration the search is allowed to run.
	// If the timer expires, the search returns the best move found
	// from the last fully completed depth.
	MaxTime time.Duration

	// MaxNodes is the maximum number of positions (nodes) the engine
	// will visit before aborting the search.
	MaxNodes int64

	// MaxDepth is the maximum number of plies (half-moves) to search.
	MaxDepth int

	// Moves is an optional list of specific moves to search. If empty,
	// the engine considers all legal moves in the position.
	Moves []Move

	// EvalFunc is the evaluation function used to score leaf nodes
	// in the search tree.
	EvalFunc EvalFunc

	// Optionally you can pass a transposition table to be used
	TranspositionTable *TranspositionTable
}

SearchOptions defines the constraints and heuristics used by the search engine to determine the best move. It allows for limiting the search by time, node count, or recursion depth.

type Square

type Square int8

Square identifies a board square by its index. The encoding places a8 at index 0 and h1 at index 63, matching the LSB-first bitboard layout:

a8=0  b8=1  ... h8=7
a7=8  b7=9  ... h7=15
...
a1=56 b1=57 ... h1=63

SQ_NULL is the sentinel value for "no square".

const (
	SQ_A8 Square = iota
	SQ_B8
	SQ_C8
	SQ_D8
	SQ_E8
	SQ_F8
	SQ_G8
	SQ_H8
	SQ_A7
	SQ_B7
	SQ_C7
	SQ_D7
	SQ_E7
	SQ_F7
	SQ_G7
	SQ_H7
	SQ_A6
	SQ_B6
	SQ_C6
	SQ_D6
	SQ_E6
	SQ_F6
	SQ_G6
	SQ_H6
	SQ_A5
	SQ_B5
	SQ_C5
	SQ_D5
	SQ_E5
	SQ_F5
	SQ_G5
	SQ_H5
	SQ_A4
	SQ_B4
	SQ_C4
	SQ_D4
	SQ_E4
	SQ_F4
	SQ_G4
	SQ_H4
	SQ_A3
	SQ_B3
	SQ_C3
	SQ_D3
	SQ_E3
	SQ_F3
	SQ_G3
	SQ_H3
	SQ_A2
	SQ_B2
	SQ_C2
	SQ_D2
	SQ_E2
	SQ_F2
	SQ_G2
	SQ_H2
	SQ_A1
	SQ_B1
	SQ_C1
	SQ_D1
	SQ_E1
	SQ_F1
	SQ_G1
	SQ_H1
	SQ_NULL
)

func ParseSquare

func ParseSquare(s string) (Square, error)

ParseSquare parses a two-character algebraic square name such as "e4" and returns the corresponding Square. Returns SQ_NULL and an error if the string is not exactly two characters or the rank/file values are out of range.

func SquareFromRankAndFile

func SquareFromRankAndFile(rank, file int8) Square

SquareFromRankAndFile constructs a Square from a rank (0=rank1 .. 7=rank8) and file (0=a .. 7=h).

func (Square) File

func (s Square) File() int8

File returns the file of the square (0=a .. 7=h).

func (Square) Rank

func (s Square) Rank() int8

Rank returns the rank of the square (0=rank1 .. 7=rank8).

func (Square) RankAndFile

func (s Square) RankAndFile() (int8, int8)

RankAndFile returns the rank (0=rank1 .. 7=rank8) and file (0=a .. 7=h) of the square.

func (Square) String

func (s Square) String() string

String returns the algebraic name of the square (e.g. "e4"), or "-" for SQ_NULL. This is the format used in FEN strings.

type TranspositionTable added in v0.3.0

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

func NewTranspositionTable added in v0.3.0

func NewTranspositionTable(maxSize uint64) *TranspositionTable

Directories

Path Synopsis
internal
cmd/book command
cmd/const command

Jump to

Keyboard shortcuts

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