Documentation
¶
Overview ¶
Package chess provides a chess engine implementation using bitboard representation.
The package uses bitboards (64-bit integers) to represent the chess board state, where each bit corresponds to a square on the board. The squares are numbered from 0 to 63, starting from the most significant bit (A1) to the least significant bit (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
A bit value of 1 indicates the presence of a piece, while 0 indicates an empty square.
Usage:
// Create a new bitboard with pieces on A1 and E4
squares := map[Square]bool{
NewSquare(FileA, Rank1): true,
NewSquare(FileE, Rank4): true,
}
bb := newBitboard(squares)
// Check if E4 is occupied
if bb.Occupied(NewSquare(FileE, Rank4)) {
fmt.Println("E4 is occupied")
}
// Print board representation
fmt.Println(bb.Draw())
Package chess is a go library designed to accomplish the following:
- chess game state and move tree management
- move validation
- PGN encoding / decoding
- FEN encoding / decoding
Game values are mutable and are not safe for concurrent use by multiple goroutines. Callers that share a Game between goroutines must provide their own synchronization.
Using Moves
game := chess.NewGame() moves := game.ValidMoves() game.Move(moves[0], nil)
Using Strict SAN Move Text
game := chess.NewGame()
game.MoveText("e4", SAN(), nil)
Using PGN
game, _ := chess.ParsePGN(pgnReader)
Using FEN
fen, _ := chess.FEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
game := chess.NewGame(fen)
Random Game
package main
import (
"fmt"
"math/rand/v2"
"github.com/corentings/chess/v3"
)
func main() {
game := chess.NewGame()
// generate moves until game is over
for game.Outcome() == chess.NoOutcome {
// select a random move
moves := game.ValidMoves()
move := moves[rand.IntN(len(moves))]
game.Move(move, nil)
}
// print outcome and game PGN
fmt.Println(game.Position().Board().Draw())
fmt.Printf("Game completed. %s by %s.\n", game.Outcome(), game.Method())
fmt.Println(game.String())
}
Package chess provides PGN lexical analysis through a lexer that converts PGN text into a stream of tokens. The lexer handles all standard PGN notation including moves, annotations, comments, and game metadata. The lexer provides token-by-token processing of PGN content with proper handling of chess-specific notation and PGN syntax rules. Example usage:
// Create new lexer
lexer := NewLexer("[Event \"World Championship\"] 1. e4 e5 {Opening}")
// Process tokens
for {
token := lexer.NextToken()
if token.Type == EOF {
break
}
// Process token
}
Index ¶
- Variables
- func DecodePGNGamesParallel(ctx context.Context, r io.Reader, opts PGNParallelOptions) <-chan PGNResult
- func FEN(fen string) (func(*Game), error)
- func GetPolyglotHashes() []string
- func HashFromFEN(fen string) (uint64, error)
- func IgnoreFivefoldRepetitionDraw() func(*Game)
- func IgnoreInsufficientMaterialDraw() func(*Game)
- func IgnoreSeventyFiveMoveRuleDraw() func(*Game)
- func MoveToPolyglot(m Move) uint16
- func PGNEvents(r io.Reader, opts ...PGNOption) iter.Seq2[PGNEvent, error]
- func PGNGames(r io.Reader, opts ...PGNOption) iter.Seq2[*Game, error]
- func PGNRecords(ctx context.Context, r io.Reader, opts ...PGNOption) iter.Seq2[PGNRecord, error]
- func ParseNAG(s string) (string, error)
- func ValidateSAN(s string) error
- type Bitboard
- func BishopAttacks(sq Square, occupied Bitboard) Bitboard
- func KingAttacks(sq Square) Bitboard
- func KnightAttacks(sq Square) Bitboard
- func NewBitboardFromSquares(squares ...Square) Bitboard
- func PawnAttacks(sq Square, c Color) Bitboard
- func QueenAttacks(sq Square, occupied Bitboard) Bitboard
- func RookAttacks(sq Square, occupied Bitboard) Bitboard
- func (bb Bitboard) And(other Bitboard) Bitboard
- func (bb Bitboard) Draw() string
- func (bb Bitboard) FirstSquare() Square
- func (bb Bitboard) Intersects(other Bitboard) bool
- func (bb Bitboard) IsEmpty() bool
- func (bb Bitboard) LastSquare() Square
- func (bb Bitboard) MarshalText() ([]byte, error)
- func (bb Bitboard) Not() Bitboard
- func (bb Bitboard) Or(other Bitboard) Bitboard
- func (bb Bitboard) Popcount() int
- func (bb Bitboard) Squares(yield func(Square) bool)
- func (bb Bitboard) String() string
- func (bb Bitboard) Subtract(other Bitboard) Bitboard
- func (bb *Bitboard) UnmarshalText(text []byte) error
- func (bb Bitboard) Xor(other Bitboard) Bitboard
- type Board
- func (b *Board) Black() Bitboard
- func (b *Board) Color(c Color) Bitboard
- func (b *Board) Draw() string
- func (b *Board) Draw2(perspective Color, darkMode bool) string
- func (b *Board) Empty() Bitboard
- func (b *Board) Flip(fd FlipDirection) (*Board, error)
- func (b *Board) HasInsufficientMaterial(c Color) bool
- func (b *Board) MarshalBinary() ([]byte, error)
- func (b *Board) MarshalText() ([]byte, error)
- func (b *Board) Occupied() Bitboard
- func (b *Board) Piece(sq Square) Piece
- func (b *Board) Pieces(pt PieceType, c Color) Bitboard
- func (b *Board) Rotate() (*Board, error)
- func (b *Board) SquareMap() map[Square]Piece
- func (b *Board) String() string
- func (b *Board) Transpose() (*Board, error)
- func (b *Board) UnmarshalBinary(data []byte) error
- func (b *Board) UnmarshalText(text []byte) error
- func (b *Board) White() Bitboard
- type CastleRights
- type Color
- type CommentBlock
- type CommentItem
- type CommentItemKind
- type File
- type FlipDirection
- type Game
- func (g *Game) AddTagPair(k, v string) bool
- func (g *Game) ClearOutcome()
- func (g *Game) Clone() *Game
- func (g *Game) Draw(method Method) error
- func (g *Game) EligibleDraws() []Method
- func (g *Game) FEN() string
- func (g *Game) GetTagPair(k string) string
- func (g *Game) IsAtEnd() bool
- func (g *Game) IsAtStart() bool
- func (g *Game) MarshalText() ([]byte, error)
- func (g *Game) Method() Method
- func (g *Game) Move(move Move, options *MoveInsertOptions) (*MoveNode, error)
- func (g *Game) MoveList() MoveList
- func (g *Game) MoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)
- func (g *Game) MoveTree() *MoveTree
- func (g *Game) Moves() []Move
- func (g *Game) NullMove(options ...*MoveInsertOptions) (*MoveNode, error)
- func (g *Game) Outcome() Outcome
- func (g *Game) Position() *Position
- func (g *Game) Positions() []*Position
- func (g *Game) PushMove(algebraicMove string, options *MoveInsertOptions) (*MoveNode, error)deprecated
- func (g *Game) PushMoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)deprecated
- func (g *Game) RemoveTagPair(k string) bool
- func (g *Game) Resign(color Color) error
- func (g *Game) SetOutcomeMethod(pair OutcomeMethodPair) error
- func (g *Game) Split() []*Game
- func (g *Game) String() string
- func (g *Game) UnmarshalText(text []byte) error
- func (g *Game) UnsafeMove(move Move, options *MoveInsertOptions) (*MoveNode, error)
- func (g *Game) UnsafeMoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)
- func (g *Game) UnsafeMoves() []Move
- func (g *Game) UnsafePushMoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)deprecated
- func (g *Game) ValidMoves() []Move
- func (g *Game) Variant() Variant
- func (g *Game) WritePGN(w io.Writer) error
- type Lexer
- type Method
- type Move
- type MoveInsertOptions
- type MoveList
- type MoveListEntry
- type MoveNode
- func (n *MoveNode) AddComment(comment string)
- func (n *MoveNode) AddNAG(nag string) error
- func (n *MoveNode) Children() []*MoveNode
- func (n *MoveNode) ChildrenIter(yield func(*MoveNode) bool)
- func (n *MoveNode) CommentBlocks() []CommentBlock
- func (n *MoveNode) Comments() string
- func (n *MoveNode) FullMoveNumber() int
- func (n *MoveNode) GetCommand(key string) (string, bool)
- func (n *MoveNode) Move() Move
- func (n *MoveNode) NAGs() []string
- func (n *MoveNode) Number() int
- func (n *MoveNode) Parent() *MoveNode
- func (n *MoveNode) Ply() int
- func (n *MoveNode) Position() *Position
- func (n *MoveNode) SetCommand(key, value string)
- func (n *MoveNode) SetComment(comment string)
- func (n *MoveNode) SetNAGs(nags []string) error
- type MoveTag
- type MoveTextCodec
- func (c MoveTextCodec) Decode(pos *Position, s string) (Move, error)
- func (c MoveTextCodec) DecodeRaw(s string) (RawMoveText, error)
- func (c MoveTextCodec) Encode(pos *Position, m Move) (string, error)
- func (c MoveTextCodec) Format() MoveTextFormat
- func (c MoveTextCodec) Policy() MoveTextPolicy
- func (c MoveTextCodec) String() string
- func (c MoveTextCodec) ValidateSyntax(s string) error
- type MoveTextFormat
- type MoveTextPolicy
- type MoveTree
- func (t *MoveTree) AddVariation(parent *MoveNode, move Move) (*MoveNode, error)
- func (t *MoveTree) Clone() *MoveTree
- func (t *MoveTree) Continuations(parent *MoveNode) []*MoveNode
- func (t *MoveTree) Current() *MoveNode
- func (t *MoveTree) Forward(idx int) bool
- func (t *MoveTree) GoBack() bool
- func (t *MoveTree) GoForward() bool
- func (t *MoveTree) Goto(node *MoveNode) bool
- func (t *MoveTree) Lines() [][]*MoveNode
- func (t *MoveTree) MainChild(parent *MoveNode) *MoveNode
- func (t *MoveTree) MainLine() []*MoveNode
- func (t *MoveTree) NavigateToMainLine()
- func (t *MoveTree) Peek() *Position
- func (t *MoveTree) Reset()
- func (t *MoveTree) Root() *MoveNode
- func (t *MoveTree) Variations(parent *MoveNode) []*MoveNode
- type MoveWithWeight
- type Outcome
- type OutcomeMethodPair
- type PGNDecoder
- type PGNError
- type PGNEvent
- type PGNEventKind
- type PGNOption
- type PGNParallelOptions
- type PGNRecord
- type PGNRenderer
- type PGNResult
- type Parser
- type ParserError
- type Piece
- type PieceType
- type PolyglotBook
- func (book *PolyglotBook) AddMove(positionHash uint64, move Move, weight uint16)
- func (book *PolyglotBook) ChessMoves(positionHash uint64) ([]Move, error)
- func (book *PolyglotBook) DeleteMoves(positionHash uint64)
- func (book *PolyglotBook) FindMoves(positionHash uint64) []PolyglotEntry
- func (book *PolyglotBook) RandomMove(positionHash uint64) (*PolyglotEntry, error)
- func (book *PolyglotBook) ToMoveMap() map[uint64][]MoveWithWeight
- func (book *PolyglotBook) UpdateMove(positionHash uint64, move Move, newWeight uint16) error
- type PolyglotEntry
- type PolyglotMove
- type Position
- func (pos *Position) AnyLegalMove() bool
- func (pos *Position) Board() *Board
- func (pos *Position) CastleRights() CastleRights
- func (pos *Position) Checkers() []Square
- func (pos *Position) Divide(depth int) map[Move]uint64
- func (pos *Position) EnPassantSquare() Square
- func (pos *Position) HalfMoveClock() int
- func (pos *Position) HasInsufficientMaterial(c Color) bool
- func (pos *Position) IsCheck() bool
- func (pos *Position) IsLegal(m Move) bool
- func (pos *Position) LegalEnPassantSquare() Square
- func (pos *Position) LegalMovesFast() []Move
- func (pos *Position) MarshalBinary() ([]byte, error)
- func (pos *Position) MarshalText() ([]byte, error)
- func (pos *Position) Outcome() Outcome
- func (pos *Position) Perft(depth int) uint64
- func (pos *Position) Ply() int
- func (pos *Position) PositionKey() string
- func (pos *Position) SamePosition(pos2 *Position) bool
- func (pos *Position) Status() Method
- func (pos *Position) String() string
- func (pos *Position) Turn() Color
- func (pos *Position) UnmarshalBinary(data []byte) error
- func (pos *Position) UnmarshalText(text []byte) error
- func (pos *Position) UnsafeMoves() []Move
- func (pos *Position) Update(m Move) *Position
- func (pos *Position) ValidMoves() []Move
- func (pos *Position) ValidMovesIter(yield func(Move) bool)
- func (pos *Position) ValidMovesUnsafe() []Move
- func (pos *Position) Variant() Variant
- func (pos *Position) XFENString() string
- func (pos *Position) ZobristHash() uint64
- type Rank
- type RawMoveText
- type Setup
- type Side
- type Square
- type TagPairs
- type Token
- type TokenType
- type Variant
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrUnterminatedComment = func(pos int) error { return &PGNError{"unterminated comment", pos} } ErrUnterminatedQuote = func(pos int) error { return &PGNError{"unterminated quote", pos} } ErrInvalidCommand = func(pos int) error { return &PGNError{"invalid command in comment", pos} } ErrInvalidPiece = func(pos int) error { return &PGNError{"invalid piece", pos} } ErrInvalidSquare = func(pos int) error { return &PGNError{"invalid square", pos} } ErrInvalidRank = func(pos int) error { return &PGNError{"invalid rank", pos} } // ErrInvalidFEN is the sentinel for any FEN parse failure. Specific // causes are wrapped with %w so callers can errors.Is(err, ErrInvalidFEN) // without inspecting message text. ErrInvalidFEN = errors.New("chess: invalid FEN") // ErrInvalidPGN is the sentinel for any PGN parse failure, including // empty input. Branch on this for "the PGN did not yield a Game". ErrInvalidPGN = errors.New("chess: invalid PGN") // ErrNoGameFound is returned when the PGN input contains no game. It // wraps ErrInvalidPGN so errors.Is(err, ErrInvalidPGN) also matches. ErrNoGameFound = fmt.Errorf("%w: no game found in PGN data", ErrInvalidPGN) // ErrGameAlreadyEnded is returned when a move is applied to a Game that // already has a terminal Outcome. Callers must ClearOutcome first. ErrGameAlreadyEnded = errors.New("chess: game already ended") )
Package-level error sentinels and constructors used throughout the PGN parser. These are immutable factories, not mutable global state, so the gochecknoglobals warning is a false positive.
var ( // ErrInvalidMoveText indicates syntactically invalid or unresolvable move text. ErrInvalidMoveText = errors.New("chess: invalid move text") // ErrMoveTextMissingPosition indicates that a codec operation needs a position. ErrMoveTextMissingPosition = errors.New("chess: move text requires position") // ErrMoveTextUnsupportedRawDecode indicates that a format cannot be decoded // without a position. ErrMoveTextUnsupportedRawDecode = errors.New("chess: move text raw decode unsupported") // ErrInvalidMoveTextCodec indicates an impossible codec format/policy pair. ErrInvalidMoveTextCodec = errors.New("chess: invalid move text codec") // ErrUnsafeMoveTextUnsupported indicates that a codec cannot be used with // unsafe move-text insertion. ErrUnsafeMoveTextUnsupported = errors.New("chess: unsafe move text unsupported") )
var DefaultPGNRenderer = &PGNRenderer{}
DefaultPGNRenderer is the package-level renderer used by Game.String and Game.WritePGN.
var ErrIllegalMove = errors.New("chess: illegal move")
ErrIllegalMove is returned by resolveCanonicalMove when the supplied coordinates do not match any legal move from the given Position.
Functions ¶
func DecodePGNGamesParallel ¶
func DecodePGNGamesParallel(ctx context.Context, r io.Reader, opts PGNParallelOptions) <-chan PGNResult
DecodePGNGamesParallel decodes PGN records across worker goroutines.
func FEN ¶
FEN takes a string and returns a function that updates the game to reflect the FEN data. Since FEN doesn't encode prior moves, the move list will be empty. The returned function is designed to be used in the NewGame constructor. An error is returned if there is a problem parsing the FEN data.
func GetPolyglotHashes ¶
func GetPolyglotHashes() []string
GetPolyglotHashes returns a reference to the static hash array.
func HashFromFEN ¶
HashFromFEN computes the Zobrist hash of a chess position from its FEN string.
func IgnoreFivefoldRepetitionDraw ¶
func IgnoreFivefoldRepetitionDraw() func(*Game)
IgnoreFivefoldRepetitionDraw returns a Game option that disables automatic draws caused by the fivefold repetition rule. When applied, the game will not automatically end in a draw if the same position occurs five times.
func IgnoreInsufficientMaterialDraw ¶
func IgnoreInsufficientMaterialDraw() func(*Game)
IgnoreInsufficientMaterialDraw returns a Game option that disables automatic draws caused by insufficient material. When applied, the game will not automatically end in a draw even if checkmate is impossible with the remaining pieces.
func IgnoreSeventyFiveMoveRuleDraw ¶
func IgnoreSeventyFiveMoveRuleDraw() func(*Game)
IgnoreSeventyFiveMoveRuleDraw returns a Game option that disables automatic draws triggered by the seventy-five move rule. When applied, the game will not automatically end in a draw if one hundred fifty half-moves pass without a pawn move or capture.
func MoveToPolyglot ¶
func PGNRecords ¶
PGNRecords returns an iterator over raw PGN records.
func ParseNAG ¶
ParseNAG normalises a NAG spelling to its canonical numeric "$N" form.
It accepts:
- any numeric NAG written as "$" followed by one or more digits (the six standard codes as well as ChessBase-style extended codes such as "$1406"),
- the six move-quality symbolic spellings (! ? !! ?? !? ?!), which are mapped to their canonical numeric codes.
Leading zeros in a numeric NAG are stripped ("$01" becomes "$1").
It rejects malformed input such as "", "$", "$x", "$ 1", "!!!", or any other unrecognised spelling.
ParseNAG always returns the canonical numeric "$N" form, never a symbol.
func ValidateSAN ¶
ValidateSAN checks if a string is valid Standard Algebraic notation (SAN) syntax. This function only validates the syntax, not whether the move is legal in any position. Examples of valid SAN: "e4", "Nf3", "O-O", "Qxd2+", "e8=Q#".
Types ¶
type Bitboard ¶
type Bitboard uint64
Bitboard is a public 64-bit set of squares. It is backed by a uint64 where the most significant bit represents A1 and the least significant bit represents H8, matching the internal bitboard layout.
func BishopAttacks ¶
BishopAttacks returns the set of squares a bishop on sq attacks given the supplied occupied squares.
func KingAttacks ¶
KingAttacks returns the set of squares a king on sq attacks.
func KnightAttacks ¶
KnightAttacks returns the set of squares a knight on sq attacks.
func NewBitboardFromSquares ¶
NewBitboardFromSquares returns a Bitboard with the given squares set.
func PawnAttacks ¶
PawnAttacks returns the set of squares a pawn of color c on sq attacks.
func QueenAttacks ¶
QueenAttacks returns the set of squares a queen on sq attacks given the supplied occupied squares. It is the union of the bishop and rook attacks.
func RookAttacks ¶
RookAttacks returns the set of squares a rook on sq attacks given the supplied occupied squares.
func (Bitboard) Draw ¶
Draw returns an 8x8 visual representation of the bitboard useful for debugging.
func (Bitboard) FirstSquare ¶
FirstSquare returns the most significant set square. It panics if bb is empty.
func (Bitboard) Intersects ¶
Intersects reports whether bb and other share at least one square.
func (Bitboard) LastSquare ¶
LastSquare returns the least significant set square. It panics if bb is empty.
func (Bitboard) MarshalText ¶
MarshalText implements encoding.TextMarshaler using the 64-character binary string representation.
func (Bitboard) Squares ¶
Squares yields every set square using Go 1.23's range-over-func pattern.
Example:
for sq := range bb.Squares {
// process square
}
func (Bitboard) String ¶
String returns a 64-character string of '1's and '0's starting with the most significant bit (A1). This matches the internal bitboard.String() format and round-trips unambiguously.
func (*Bitboard) UnmarshalText ¶
UnmarshalText implements encoding.TextUnmarshaler from the 64-character binary string representation.
type Board ¶
type Board struct {
// contains filtered or unexported fields
}
Board represents a chess board and its relationship between squares and pieces. It maintains separate bitboards for each piece type and color, along with convenience bitboards for quick position analysis.
func NewBoard ¶
NewBoard returns a board from a square to piece mapping. The map should contain only occupied squares.
Example:
squares := map[Square]Piece{
NewSquare(FileE, Rank1): WhiteKing,
NewSquare(FileE, Rank8): BlackKing,
}
board, err := NewBoard(squares)
func (*Board) Draw ¶
Draw returns a visual ASCII representation of the board. Capital letters represent white pieces, lowercase represent black pieces. Empty squares are shown as "-".
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
func (*Board) Draw2 ¶
Draw2 returns visual representation of the board useful for debugging. It is similar to Draw() except allows the caller to specify perspective and dark mode options.
func (*Board) Flip ¶
func (b *Board) Flip(fd FlipDirection) (*Board, error)
Flip returns a new board flipped over the specified axis. For UpDown, pieces are mirrored across the horizontal center line. For LeftRight, pieces are mirrored across the vertical center line.
func (*Board) HasInsufficientMaterial ¶
HasInsufficientMaterial reports whether color c cannot force checkmate against any opposing material. It returns true for a lone king, king plus a single minor piece, or king plus bishops that are all confined to one square color. It returns false when c has a queen, rook, pawn, knight, or bishops on both square colors.
func (*Board) MarshalBinary ¶
MarshalBinary implements the encoding.BinaryMarshaler interface and returns the bitboard representations as a array of bytes. Bitboads are encoded in the following order: WhiteKing, WhiteQueen, WhiteRook, WhiteBishop, WhiteKnight WhitePawn, BlackKing, BlackQueen, BlackRook, BlackBishop, BlackKnight, BlackPawn.
func (*Board) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface and returns a string in the FEN board format: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR.
func (*Board) Piece ¶
Piece returns the piece for the given square. Returns NoPiece if the square is empty.
func (*Board) SquareMap ¶
SquareMap returns a mapping of squares to pieces. A square is only added to the map if it is occupied.
func (*Board) String ¶
String implements the fmt.Stringer interface and returns a string in the FEN board format: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR.
func (*Board) UnmarshalBinary ¶
UnmarshalBinary implements the encoding.BinaryUnmarshaler interface and parses the bitboard representations as a array of bytes. Bitboads are decoded in the following order: WhiteKing, WhiteQueen, WhiteRook, WhiteBishop, WhiteKnight WhitePawn, BlackKing, BlackQueen, BlackRook, BlackBishop, BlackKnight, BlackPawn.
func (*Board) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnarshaler interface and takes a string in the FEN board format: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR.
type CastleRights ¶
type CastleRights struct {
White castleSideRights
Black castleSideRights
}
CastleRights holds the state of both sides castling abilities.
func NewCastleRights ¶
func NewCastleRights(whiteKingSide, whiteQueenSide, blackKingSide, blackQueenSide bool) CastleRights
NewCastleRights returns a CastleRights value with the four per-color, per-side flags set explicitly. It is the supported way for callers outside this package to construct a CastleRights value.
func (CastleRights) CanCastle ¶
func (cr CastleRights) CanCastle(c Color, side Side) bool
CanCastle returns true if the given color and side combination can castle.
Example:
if rights.CanCastle(White, KingSide) {
// White can castle kingside
}
func (CastleRights) MarshalText ¶
func (cr CastleRights) MarshalText() ([]byte, error)
MarshalText implements the encoding.TextMarshaler interface using the FEN representation.
func (CastleRights) String ¶
func (cr CastleRights) String() string
String implements the fmt.Stringer interface and returns a FEN compatible string in canonical order (KQkq), or "-" when no side can castle.
func (*CastleRights) UnmarshalText ¶
func (cr *CastleRights) UnmarshalText(text []byte) error
UnmarshalText implements the encoding.TextUnmarshaler interface using the FEN representation.
type Color ¶
type Color int8
Color represents the color of a chess piece.
func ColorFromString
deprecated
func ParseColor ¶
ParseColor converts a FEN side-to-move character ("w" or "b") to a Color. It returns an error for any other input.
type CommentBlock ¶
type CommentBlock struct {
Items []CommentItem
}
CommentBlock represents one PGN {...} block.
type CommentItem ¶
type CommentItem struct {
Kind CommentItemKind
Text string
Key string
Value string
}
CommentItem is one ordered item inside a PGN comment block.
type CommentItemKind ¶
type CommentItemKind int
CommentItemKind identifies the kind of item inside a PGN comment block.
const ( // CommentText is plain text inside a PGN comment block. CommentText CommentItemKind = iota // CommentCommand is a command annotation like [%clk 0:05:00]. CommentCommand )
type FlipDirection ¶
type FlipDirection int
FlipDirection is the direction for the Board.Flip method.
const ( // UpDown flips the board's rank values. UpDown FlipDirection = iota // LeftRight flips the board's file values. LeftRight )
type Game ¶
type Game struct {
// contains filtered or unexported fields
}
A Game represents a single chess game.
func NewGame ¶
NewGame returns a new game in the standard starting position. Optional functions can be provided to configure the initial game state.
Example:
// Standard game
game := NewGame()
// Game from FEN
game := NewGame(FEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"))
func ParsePGN ¶
ParsePGN parses the first Game from r. Any returned error wraps ErrInvalidPGN so callers can errors.Is(err, ErrInvalidPGN) without inspecting message text; io.EOF is returned unchanged when r yields no game.
func (*Game) AddTagPair ¶
AddTagPair adds or updates a tag pair with the given key and value and returns true if the value is overwritten.
func (*Game) ClearOutcome ¶
func (g *Game) ClearOutcome()
ClearOutcome resets the game to NoOutcome/NoMethod. It does not modify any tag in tagPairs (including the Result tag): PGN tag metadata is treated as caller-owned data, separate from the live outcome. Callers that want PGN tag parity must update tagPairs["Result"] themselves, or rebuild from the game state via Split which does sync the tag.
func (*Game) Draw ¶
Draw attempts to draw the game by the given method. If the method is valid, then the game is updated to a draw by that method. If the method isn't valid then an error is returned. Returns ErrGameAlreadyEnded if the game is already in a terminal state.
func (*Game) EligibleDraws ¶
EligibleDraws returns valid inputs for the Draw() method.
func (*Game) FEN ¶
FEN returns the FEN notation of the current position. Returns "" if the game has no current position.
func (*Game) GetTagPair ¶
GetTagPair returns the tag pair for the given key or nil if it is not present.
func (*Game) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface and encodes the game's PGN.
func (*Game) Move ¶
func (g *Game) Move(move Move, options *MoveInsertOptions) (*MoveNode, error)
Move method adds a move to the game using a Move struct. It returns an error if the move is invalid. This method validates the move before adding it to ensure game correctness. For high-performance scenarios where moves are pre-validated, use UnsafeMove.
Null moves are rejected here: they are never part of ValidMovesUnsafe, so callers wanting to pass the side must use Game.NullMove or Game.UnsafeMove explicitly.
Example:
possibleMove := game.ValidMoves()[0]
err := game.Move(possibleMove, nil)
if err != nil {
panic(err)
}
func (*Game) MoveList ¶
MoveList returns the main-line moves in order with any comments. Variations are not included. The returned slice is safe to retain: it holds no references to the game's live cursor state. Returns an empty slice for games with no moves.
func (*Game) MoveText ¶
func (g *Game) MoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)
MoveText adds a move to the game using an explicit move text codec. It decodes against the current position so the inserted move carries position-derived tags. The decoded Move is canonical (codec.Decode resolves legal moves), so it crosses the trusted fast path: no extra legal-move lookup is needed before insertion.
func (*Game) NullMove ¶
func (g *Game) NullMove(options ...*MoveInsertOptions) (*MoveNode, error)
NullMove appends a null move (a side-to-move flip with no piece movement) to the current position's main line. Null moves are never part of the legal moves returned by ValidMoves, so they cannot be inserted via Game.Move. Use this method or Game.UnsafeMove(NullMove()) to add one explicitly.
Pass nil (or no argument) to use default options.
Example ¶
package main
import (
"fmt"
"github.com/corentings/chess/v3"
)
func main() {
g := chess.NewGame()
if _, err := g.NullMove(); err != nil {
fmt.Println("Error:", err)
return
}
// A null move flips the side to move without moving any piece.
fmt.Println(g.Position().Turn())
}
Output: b
func (*Game) Positions ¶
Positions returns all positions in the game in the main line. This includes the starting position and all positions after each move. The cursor is saved and restored so the caller's active position is unchanged.
func (*Game) PushMoveText
deprecated
func (g *Game) PushMoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)
PushMoveText adds a move to the game using an explicit move text codec.
Deprecated: use MoveText instead.
func (*Game) RemoveTagPair ¶
RemoveTagPair removes the tag pair for the given key and returns true if a tag pair was removed.
func (*Game) Resign ¶
Resign resigns the game for the given color. If the game has already been completed or the color is invalid, Resign returns an error and does not update the game.
func (*Game) SetOutcomeMethod ¶
func (g *Game) SetOutcomeMethod(pair OutcomeMethodPair) error
SetOutcomeMethod sets the game's outcome and method together after validating that the pair is internally consistent. It returns an error for invalid pairs such as WhiteWon with Stalemate or Draw with Checkmate. It does not modify any Result tag in tagPairs.
Example ¶
package main
import (
"fmt"
"github.com/corentings/chess/v3"
)
func main() {
g := chess.NewGame()
if err := g.SetOutcomeMethod(chess.OutcomeMethodPair{
Outcome: chess.WhiteWon,
Method: chess.Resignation,
}); err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(g.Outcome(), g.Method())
}
Output: 1-0 Resignation
func (*Game) Split ¶
Split takes a Game with a main line and 0 or more variations and returns a slice of Games (one for each variation), each containing exactly only a main line and 0 variations.
func (*Game) String ¶
String implements the fmt.Stringer interface and returns the game's PGN. It delegates to DefaultPGNRenderer.
func (*Game) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface and assumes the data is in the PGN format.
func (*Game) UnsafeMove ¶
func (g *Game) UnsafeMove(move Move, options *MoveInsertOptions) (*MoveNode, error)
UnsafeMove adds a move to the game without validation. This method is intended for high-performance scenarios where moves are known to be valid. Use this method only when you have already validated the move or are certain it's legal. For general use, prefer the Move method which includes validation.
Example:
// Only use when you're certain the move is valid
validMoves := game.ValidMoves()
move := validMoves[0] // We know this is valid
err := game.UnsafeMove(move, nil)
if err != nil {
panic(err) // Should not happen with valid moves
}
func (*Game) UnsafeMoveText ¶
func (g *Game) UnsafeMoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)
UnsafeMoveText adds fully specified move text without legal move verification. It supports only codecs that can raw-decode a move without SAN resolution.
func (*Game) UnsafeMoves ¶
UnsafeMoves returns all pseudo-legal moves that leave the moving side's king in check. These moves are valid piece movements but illegal because they expose the king.
func (*Game) UnsafePushMoveText
deprecated
func (g *Game) UnsafePushMoveText(moveText string, codec MoveTextCodec, options *MoveInsertOptions) (*MoveNode, error)
UnsafePushMoveText adds fully specified move text without legal move verification.
Deprecated: use UnsafeMoveText instead.
func (*Game) ValidMoves ¶
ValidMoves returns all legal moves in the current position.
type Lexer ¶
type Lexer struct {
// contains filtered or unexported fields
}
Lexer provides lexical analysis of PGN text.
func NewLexer ¶
NewLexer creates a new Lexer for the provided input text. The lexer is initialized and ready to produce tokens through calls to NextToken().
Example:
lexer := NewLexer("1. e4 e5")
func (*Lexer) NextToken ¶
NextToken reads the next token from the input stream. Returns an EOF token when the input is exhausted. Returns an ILLEGAL token for invalid input.
The method handles all standard PGN notation including: - Move notation (e4, Nf3, O-O) - Comments ({comment} or ; comment) - Tags ([Event "World Championship"]) - Move numbers and variations - Annotations ($1, !!, ?!)
Example:
lexer := NewLexer("1. e4 {Strong move}")
token := lexer.NextToken() // NUMBER: "1"
token = lexer.NextToken() // DOT: "."
token = lexer.NextToken() // NOTATION: "e4"
token = lexer.NextToken() // COMMENT: "Strong move"
token = lexer.NextToken() // EOF
type Method ¶
type Method uint8
A Method is the method that generated the outcome.
const ( // NoMethod indicates that an outcome hasn't occurred or that the method can't be determined. NoMethod Method = iota // Checkmate indicates that the game was won checkmate. Checkmate // Resignation indicates that the game was won by resignation. Resignation // DrawOffer indicates that the game was drawn by a draw offer. DrawOffer // Stalemate indicates that the game was drawn by stalemate. Stalemate // ThreefoldRepetition indicates that the game was drawn when the game // state was repeated three times and a player requested a draw. ThreefoldRepetition // FivefoldRepetition indicates that the game was automatically drawn // by the game state being repeated five times. FivefoldRepetition // FiftyMoveRule indicates that the game was drawn by the half // move clock being one hundred or greater when a player requested a draw. FiftyMoveRule // SeventyFiveMoveRule indicates that the game was automatically drawn // when the half move clock was one hundred and fifty or greater. SeventyFiveMoveRule // InsufficientMaterial indicates that the game was automatically drawn // because there was insufficient material for checkmate. InsufficientMaterial )
type Move ¶
type Move struct {
// contains filtered or unexported fields
}
A Move is the movement of a piece from one square to another.
func NewMove ¶
NewMove returns a Move from origin square s1 to destination square s2. The optional promo argument supplies a promotion piece type; when omitted the move has no promotion. Tags default to none.
The constructor does not attempt to infer Capture or Check tags because those depend on the position context (the piece on s1, the occupant of s2, and whether the move leaves the opponent in check). Use Position.IsLegal or Game.Move to obtain a fully tagged canonical Move when the position is known.
func NewNullMove ¶
func NewNullMove() Move
NewNullMove returns a Move that flips the side to move without moving any piece. The returned move carries the Null MoveTag and has no origin, destination, or promotion. Null moves must be inserted via Game.NullMove or Game.UnsafeMove; they are rejected by Game.Move because they are never part of a position's legal moves.
type MoveInsertOptions ¶
type MoveInsertOptions struct {
// PromoteToMainLine makes the inserted or selected continuation the main line.
PromoteToMainLine bool
}
MoveInsertOptions contains options for inserting a move into a MoveTree.
type MoveList ¶
type MoveList []MoveListEntry
MoveList is the main-line move sequence of a game. Variations are not included. The zero value is an empty list; use Game.MoveList to obtain one.
type MoveListEntry ¶
MoveListEntry is a single move in a MoveList: the move itself plus any comments attached to it. Positions are not cached here — callers that need the pre/post position replay it via Game.MoveTree and the cursor API.
type MoveNode ¶
type MoveNode struct {
// contains filtered or unexported fields
}
MoveNode is one occurrence of a move in a game's move tree.
func (*MoveNode) AddComment ¶
func (*MoveNode) AddNAG ¶
AddNAG normalises and appends a single NAG to the move node. Order is preserved. A malformed value leaves the node unchanged.
func (*MoveNode) ChildrenIter ¶
ChildrenIter returns an allocation-free iterator over the continuations.
func (*MoveNode) CommentBlocks ¶
func (n *MoveNode) CommentBlocks() []CommentBlock
CommentBlocks returns a defensive copy of the move node's structured PGN comment blocks.
func (*MoveNode) FullMoveNumber ¶
FullMoveNumber returns the full move number (increments after Black's move).
func (*MoveNode) NAGs ¶
NAGs returns a defensive copy of the move node's numeric annotation glyphs in their canonical "$N" form, in the order they were added.
func (*MoveNode) Ply ¶
Ply returns the half-move number (increments every move). For the synthetic root it returns 0; otherwise it equals the depth of the parent chain from n up to (not including) the synthetic root.
func (*MoveNode) Position ¶
Position returns the position reached by playing this node's move from its parent's position. It saves and restores the tree's active cursor so the read is observationally pure under ADR-016's single-active-cursor invariant. See ADR-018 for the lazy-position design.
func (*MoveNode) SetCommand ¶
func (*MoveNode) SetComment ¶
type MoveTag ¶
type MoveTag uint16
A MoveTag represents a notable consequence of a move.
const ( // KingSideCastle indicates that the move is a king side castle. KingSideCastle MoveTag = 1 << iota // QueenSideCastle indicates that the move is a queen side castle. QueenSideCastle // Capture indicates that the move captures a piece. Capture // EnPassant indicates that the move captures via en passant. EnPassant // Check indicates that the move puts the opposing player in check. Check // Null indicates that the move flips the side to move without moving // any piece. Null moves are encoded as "Z0" in PGN and "0000" in UCI. // They are never generated by ValidMoves and must be inserted // explicitly via Game.NullMove or Game.UnsafeMove. Null )
type MoveTextCodec ¶
type MoveTextCodec struct {
// contains filtered or unexported fields
}
MoveTextCodec parses, resolves, validates, and formats move text.
The zero value is the strict SAN codec returned by SAN().
func LongAlgebraic ¶
func LongAlgebraic() MoveTextCodec
LongAlgebraic returns the coordinate-expanded algebraic notation codec.
func PGNImportSAN ¶
func PGNImportSAN() MoveTextCodec
PGNImportSAN returns the permissive SAN codec used by PGN import.
func UCI ¶
func UCI() MoveTextCodec
UCI returns the Universal Chess Interface coordinate notation codec.
func (MoveTextCodec) Decode ¶
func (c MoveTextCodec) Decode(pos *Position, s string) (Move, error)
Decode resolves move text against the supplied position.
func (MoveTextCodec) DecodeRaw ¶
func (c MoveTextCodec) DecodeRaw(s string) (RawMoveText, error)
DecodeRaw decodes fully specified move text without a position.
func (MoveTextCodec) Encode ¶
func (c MoveTextCodec) Encode(pos *Position, m Move) (string, error)
Encode formats a move from the supplied position. Tag-dependent suffixes (check, capture, disambiguation) are recomputed from the resulting position rather than trusted from the input move; Decode returns already-tagged moves from the legal-move generator and does not recompute.
func (MoveTextCodec) Format ¶
func (c MoveTextCodec) Format() MoveTextFormat
Format returns the codec's move text format.
func (MoveTextCodec) Policy ¶
func (c MoveTextCodec) Policy() MoveTextPolicy
Policy returns the codec's parsing policy.
func (MoveTextCodec) String ¶
func (c MoveTextCodec) String() string
String implements fmt.Stringer.
func (MoveTextCodec) ValidateSyntax ¶
func (c MoveTextCodec) ValidateSyntax(s string) error
ValidateSyntax reports whether text matches the codec grammar without checking move legality.
type MoveTextFormat ¶
type MoveTextFormat uint8
MoveTextFormat identifies the concrete move text grammar handled by a codec.
const ( // MoveTextFormatSAN is strict Standard Algebraic notation. MoveTextFormatSAN MoveTextFormat = iota // MoveTextFormatLongAlgebraic is coordinate-expanded algebraic notation. MoveTextFormatLongAlgebraic // MoveTextFormatUCI is Universal Chess Interface coordinate notation. MoveTextFormatUCI )
type MoveTextPolicy ¶
type MoveTextPolicy uint8
MoveTextPolicy identifies how permissive a codec is while reading move text.
const ( // MoveTextPolicyStrict accepts only generated canonical text. MoveTextPolicyStrict MoveTextPolicy = iota // MoveTextPolicyPGNImport accepts documented PGN import spellings and // canonicalises them when writing. MoveTextPolicyPGNImport )
type MoveTree ¶
type MoveTree struct {
// contains filtered or unexported fields
}
MoveTree owns the move topology and active cursor for a game.
The root is a synthetic position node, not a move occurrence. The cursor's current position is tracked in pos alongside current: every navigation (addMove, GoForward, GoBack, Forward, Goto, Reset, setCurrent) advances pos via the in-place makeMoveCursor / unmakeMoveCursor pair (move_applier.go), with one entry in undos per level between root and current. rootPos holds the starting position so the cursor can be reset without re-deriving it from the synthetic root MoveNode.
func (*MoveTree) AddVariation ¶
AddVariation validates and appends move as a variation from parent. The cursor is saved and restored so the caller's active position is unchanged.
func (*MoveTree) Continuations ¶
Continuations returns all continuations from parent.
func (*MoveTree) Forward ¶
Forward advances the cursor to the idx-th child of the current node. Forward(0) is equivalent to MoveTree.GoForward (main-line continuation). Returns true on success; false if t is nil, the current node has no children, or idx is out of range.
func (*MoveTree) Goto ¶
Goto jumps the cursor to the given node. Returns true if the cursor moved. Returns false if t is nil, node is nil, or node belongs to a different tree. Goto uses the same fast paths as internal cursor navigation: direct child, LCA walk, and full replay-from-root (see [MoveTree.setCurrent]).
func (*MoveTree) MainLine ¶
MainLine returns the main-line move nodes, excluding the root position node.
func (*MoveTree) NavigateToMainLine ¶
func (t *MoveTree) NavigateToMainLine()
NavigateToMainLine moves the active cursor to the first main-line move.
func (*MoveTree) Peek ¶
Peek returns the live Position at the tree's active cursor without copying. The returned pointer aliases the tree's internal state and is valid only until the next cursor move (GoForward, GoBack, Forward, Goto, Reset, AddVariation, or any move pushed onto the tree). Callers MUST NOT mutate it; mutation corrupts the cursor and every subsequent read in the library, including legal-move generation and repetition detection.
For a snapshot you can retain or mutate, use MoveNode.Position (a defensive copy at a node) or Game.Position (a defensive copy of the current position). Both copy.
Returns nil if t is nil or has no position.
func (*MoveTree) Reset ¶
func (t *MoveTree) Reset()
Reset returns the cursor to the synthetic root, restoring the starting position. Safe to call on a nil tree.
func (*MoveTree) Variations ¶
Variations returns all non-main-line continuations from parent.
type MoveWithWeight ¶
MoveWithWeight is a helper struct that couples a chess.Move with a weight.
type Outcome ¶
type Outcome int8
A Outcome is the result of a game.
func ParseOutcome ¶
ParseOutcome converts a PGN result token into a typed Outcome. Unknown tokens return an error.
func (Outcome) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface using the PGN result token.
func (Outcome) String ¶
String implements the fmt.Stringer interface and returns the PGN result token.
func (*Outcome) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface from a PGN result token.
type OutcomeMethodPair ¶
OutcomeMethodPair pairs an Outcome with the Method that produced it.
type PGNDecoder ¶
type PGNDecoder struct {
// contains filtered or unexported fields
}
PGNDecoder streams Games from a PGN reader.
func NewPGNDecoder ¶
func NewPGNDecoder(r io.Reader, opts ...PGNOption) *PGNDecoder
NewPGNDecoder creates a decoder that reads Games from r.
func (*PGNDecoder) Decode ¶
func (d *PGNDecoder) Decode() (*Game, error)
Decode returns the next Game from the PGN stream.
func (*PGNDecoder) Index ¶
func (d *PGNDecoder) Index() int64
Index returns the number of Games successfully decoded by this decoder.
func (*PGNDecoder) Offset ¶
func (d *PGNDecoder) Offset() int64
Offset returns the byte offset of the current PGN record when available.
type PGNError ¶
type PGNError struct {
// contains filtered or unexported fields
}
PGNError custom error types for different PGN errors.
type PGNEvent ¶
type PGNEvent struct {
Kind PGNEventKind
Index int64
Offset int64
Name string
Value string
Move string
NAG string
}
PGNEvent is one semantic event from a PGN stream.
type PGNEventKind ¶
type PGNEventKind uint8
PGNEventKind identifies a semantic PGN event.
const ( PGNEventUnknown PGNEventKind = iota PGNTag PGNMove PGNComment PGNNAG PGNVariationStart PGNVariationEnd PGNGameEnd )
type PGNOption ¶
type PGNOption func(*pgnOptions)
PGNOption configures PGN decoding.
func WithImportSAN ¶
func WithImportSAN() PGNOption
WithImportSAN accepts documented PGN import SAN spellings.
func WithPGNBufferSize ¶
WithPGNBufferSize configures the reader buffer size used for PGN record framing.
func WithPGNExpandVariations ¶
func WithPGNExpandVariations() PGNOption
WithPGNExpandVariations expands each Game's Variations into separate Games.
func WithStrictSAN ¶
func WithStrictSAN() PGNOption
WithStrictSAN requires PGN movetext to use strict canonical SAN.
type PGNParallelOptions ¶
PGNParallelOptions configures parallel PGN Game decoding.
type PGNRecord ¶
PGNRecord is one complete PGN game record from a stream.
type PGNRenderer ¶
type PGNRenderer struct{}
PGNRenderer renders a Game into PGN text. It is a stateless function object that reads Game state and writes formatted PGN to a string or io.Writer without mutating the Game.
The renderer takes a pointer so callers may extend it in the future (custom tag ordering, value escaping toggles, optional result token, etc.). All such configuration fields are deferred to v3.1; this initial type is a pure extraction with no knobs.
func (*PGNRenderer) Render ¶
func (r *PGNRenderer) Render(g *Game) string
Render returns the PGN text for g.
func (*PGNRenderer) RenderGameTo ¶
func (r *PGNRenderer) RenderGameTo(g *Game, w io.Writer) error
RenderGameTo writes the PGN text for g to w. It returns any write error from w.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser holds the state needed during parsing.
func (*Parser) Parse ¶
Parse processes all tokens and returns the complete game. This includes parsing header information (tags), moves, variations, comments, and the game result.
Returns an error if the PGN is malformed or contains illegal moves.
Example:
game, err := parser.Parse()
if err != nil {
log.Fatal("Error parsing game:", err)
}
fmt.Printf("Event: %s\n", game.GetTagPair("Event"))
type ParserError ¶
func (*ParserError) Error ¶
func (e *ParserError) Error() string
type Piece ¶
type Piece int8
Piece is a piece type with a color.
const ( // NoPiece represents no piece. NoPiece Piece = iota // WhiteKing is a white king. WhiteKing // WhiteQueen is a white queen. WhiteQueen // WhiteRook is a white rook. WhiteRook // WhiteBishop is a white bishop. WhiteBishop // WhiteKnight is a white knight. WhiteKnight // WhitePawn is a white pawn. WhitePawn // BlackKing is a black king. BlackKing // BlackQueen is a black queen. BlackQueen // BlackRook is a black rook. BlackRook // BlackBishop is a black bishop. BlackBishop // BlackKnight is a black knight. BlackKnight // BlackPawn is a black pawn. BlackPawn )
func NewPiece ¶
NewPiece returns the piece matching the PieceType and Color. NoPiece is returned if the PieceType or Color isn't valid.
func (Piece) DarkString ¶
DarkString is equivalent to String() except colors reversed for terminal windows in dark mode.
type PieceType ¶
type PieceType int8
PieceType is the type of a piece.
func ParsePieceType ¶
ParsePieceType parses a single-character piece notation into a PieceType. It returns an error if the input is empty or longer than one character, or if the character is not a valid piece type.
func ParsePieceTypeFromByte ¶
ParsePieceTypeFromByte parses a FEN piece-type character (case-insensitive) into a PieceType. It returns an error for any other byte.
func PieceTypeFromByte
deprecated
func PieceTypeFromString
deprecated
func (PieceType) ToPolyglotPromotionValue ¶
type PolyglotBook ¶
type PolyglotBook struct {
// contains filtered or unexported fields
}
PolyglotBook represents a polyglot opening book with optimized lookup capabilities. A polyglot book is a binary file format widely used in chess engines to store opening moves. Each entry in the book contains a position hash, a move, and additional metadata.
Example usage:
// Load from file
book, err := LoadBookFromReader(fileReader)
if err != nil {
log.Fatal(err)
}
// Find moves for a position
hash := uint64(0x463b96181691fc9c) // Starting position hash
moves := book.FindMoves(hash)
// Get a random move weighted by the stored weights
randomMove := book.RandomMove(hash)
func LoadFromBytes ¶
func LoadFromBytes(data []byte) (*PolyglotBook, error)
LoadFromBytes loads a polyglot book from a byte slice. This is useful when the book data is already in memory.
Example:
data := // ... your book data ...
book, err := LoadFromBytes(data)
if err != nil {
log.Fatal(err)
}
func LoadFromReader ¶
func LoadFromReader(reader io.Reader) (*PolyglotBook, error)
LoadFromReader loads a polyglot book from an io.Reader. Note that this will read the entire input into memory.
Example:
file, err := os.Open("openings.bin")
if err != nil {
log.Fatal(err)
}
defer file.Close()
book, err := LoadFromReader(file)
if err != nil {
log.Fatal(err)
}
func NewPolyglotBookFromMap ¶
func NewPolyglotBookFromMap(m map[uint64][]MoveWithWeight) *PolyglotBook
NewPolyglotBookFromMap creates a PolyglotBook from a map where the key is the zobrist hash (uint64) and the value is a slice of MoveWithWeight.
func (*PolyglotBook) AddMove ¶
func (book *PolyglotBook) AddMove(positionHash uint64, move Move, weight uint16)
AddMove adds a new move (with its weight) to a given position hash in the book.
func (*PolyglotBook) ChessMoves ¶
func (book *PolyglotBook) ChessMoves(positionHash uint64) ([]Move, error)
func (*PolyglotBook) DeleteMoves ¶
func (book *PolyglotBook) DeleteMoves(positionHash uint64)
DeleteMoves removes all moves for a given position hash from the book.
func (*PolyglotBook) FindMoves ¶
func (book *PolyglotBook) FindMoves(positionHash uint64) []PolyglotEntry
FindMoves looks up all moves for a given position hash. Returns moves sorted by weight (highest weight first). Returns nil if no moves are found.
Example:
hash := uint64(0x463b96181691fc9c) // Starting position
moves := book.FindMoves(hash)
if moves != nil {
for _, move := range moves {
decodedMove := DecodeMove(move.Move)
fmt.Printf("Move: %v, Weight: %d\n", decodedMove, move.Weight)
}
}
func (*PolyglotBook) RandomMove ¶
func (book *PolyglotBook) RandomMove(positionHash uint64) (*PolyglotEntry, error)
RandomMove returns a weighted random move from the available moves for a position. The probability of selecting a move is proportional to its weight. Returns nil if no moves are available.
Example:
hash := uint64(0x463b96181691fc9c) // Starting position
move, err := book.RandomMove(hash)
if err != nil {
log.Fatal(err)
}
if move != nil {
decodedMove := DecodeMove(move.Move)
fmt.Printf("Selected move: %v\n", decodedMove)
}
func (*PolyglotBook) ToMoveMap ¶
func (book *PolyglotBook) ToMoveMap() map[uint64][]MoveWithWeight
func (*PolyglotBook) UpdateMove ¶
func (book *PolyglotBook) UpdateMove(positionHash uint64, move Move, newWeight uint16) error
UpdateMove searches for an existing move at the given position and updates its weight.
type PolyglotEntry ¶
type PolyglotEntry struct {
Key uint64 // Zobrist hash of the chess position
Move uint16 // Encoded move (see DecodeMove for format)
Weight uint16 // Relative weight for move selection
Learn uint32 // Learning data (usually 0)
}
PolyglotEntry represents a single entry in a polyglot opening book. Each entry is exactly 16 bytes and contains information about a chess position and a recommended move.
type PolyglotMove ¶
type PolyglotMove struct {
FromFile int // Source file (0-7)
FromRank int // Source rank (0-7)
ToFile int // Target file (0-7)
ToRank int // Target rank (0-7)
Promotion int // Promotion piece type (0=none, 1=knight, 2=bishop, 3=rook, 4=queen)
CastlingMove bool // True if this is a castling move
}
PolyglotMove represents a decoded chess move from a polyglot entry. The coordinates use 0-based indices where: - Files go from 0 (a-file) to 7 (h-file) - Ranks go from 0 (1st rank) to 7 (8th rank).
func DecodeMove ¶
func DecodeMove(move uint16) PolyglotMove
DecodeMove converts a polyglot move encoding into a more usable format. The move encoding uses bit fields as follows:
- bits 0-2: to file
- bits 3-5: to rank
- bits 6-8: from file
- bits 9-11: from rank
- bits 12-14: promotion piece
Promotion pieces are encoded as:
- 0: none
- 1: knight
- 2: bishop
- 3: rook
- 4: queen
Example:
move := uint16(0x1234) // Some move from the book
decoded := DecodeMove(move)
fmt.Printf("From: %c%d, To: %c%d\n",
'a'+decoded.FromFile, decoded.FromRank+1,
'a'+decoded.ToFile, decoded.ToRank+1)
func (PolyglotMove) Encode ¶
func (pm PolyglotMove) Encode() uint16
func (PolyglotMove) ToMove ¶
func (pm PolyglotMove) ToMove() Move
type Position ¶
type Position struct {
// contains filtered or unexported fields
}
Position represents a complete chess position state. It includes piece placement, castling rights, en passant squares, move counts, and side to move.
func NewPosition ¶
NewPosition validates s and constructs a playable Position from it.
Validation covers:
- exactly one king of each color
- no pawns on the first or eighth rank
- castling rights that match the king and rook placement on their starting squares
- an en passant square that is consistent with a pawn that just moved two squares
- non-negative halfmove clock and positive fullmove number
func StartingPosition ¶
func StartingPosition() *Position
StartingPosition returns the starting position rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1.
func (*Position) AnyLegalMove ¶
AnyLegalMove reports whether the position has at least one legal move.
func (*Position) CastleRights ¶
func (pos *Position) CastleRights() CastleRights
CastleRights returns the castling rights of the position.
func (*Position) Checkers ¶
Checkers returns the squares of the pieces currently giving check to the side to move. The returned slice is empty when the position is not in check. It allocates only when called.
func (*Position) Divide ¶
Divide returns the per-root-move Perft breakdown at the given depth: a map from each legal move in the current position to the number of leaf positions reachable in exactly depth-1 further plies after that move. It is the per-move form of Perft and is typically used to localize a divergence between two move generators.
Like Perft, a depth of 0 returns a single-entry map for the current position (the move is the zero Move, count 1). A position with no legal moves returns an empty map for any depth greater than 0.
The map iteration order is unspecified; sort by key if a stable display is required.
Example:
pos := chess.StartingPosition()
results := pos.Divide(1)
for _, m := range sortedMoves(results) {
fmt.Printf("%s: %d\n", m, results[m])
}
func (*Position) EnPassantSquare ¶
EnPassantSquare returns the raw en-passant target square set after any double pawn push, even when no enemy pawn can capture it. This is the FEN en-passant field.
func (*Position) HalfMoveClock ¶
HalfMoveClock returns the half-move clock (50-rule).
func (*Position) HasInsufficientMaterial ¶
HasInsufficientMaterial reports whether color c cannot force checkmate with its remaining material against any opposing material.
func (*Position) IsLegal ¶
IsLegal reports whether m is a legal move in the current position. It returns false for null moves and for moves whose origin square belongs to the side not to move. The check is a linear scan of the legal move list; callers who need the canonical Move with position-derived tags should use Game.Move or resolveCanonicalMove.
func (*Position) LegalEnPassantSquare ¶
LegalEnPassantSquare returns the en-passant target square only if an enemy pawn can actually capture en passant; otherwise it returns NoSquare. This is the value that feeds the Zobrist hash.
func (*Position) LegalMovesFast ¶
LegalMovesFast returns legal moves in the same stable generation order as ValidMovesUnsafe without computing display-only check annotations. The returned moves remain valid inputs to Position.Update. This is intended for replay/index codecs that need move identity and legality but not SAN tags.
func (*Position) MarshalBinary ¶
MarshalBinary implements the encoding.BinaryMarshaler interface.
func (*Position) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface and encodes the position's FEN.
func (*Position) Outcome ¶
Outcome returns the decisive or draw outcome implied by the position, or NoOutcome if play continues. It considers board-state terminal conditions only: checkmate, stalemate, insufficient material, and the seventy-five move rule. Game-level outcomes such as resignation, draw offer, and the claimable fifty-move rule are not included and must be queried on Game.
func (*Position) Perft ¶
Perft (performance test) counts the number of legal move sequences of the given length reachable from the receiver. It is a standard correctness and performance test for chess move generators.
A depth of 0 counts the current position itself. A depth of 1 counts the number of legal moves. Otherwise each legal move is applied in turn and the counts are summed recursively.
Perft is purely a node counter; it does not collect, store, or annotate the move sequences. For a per-root-move breakdown use Divide.
Example:
pos := chess.StartingPosition() nodes := pos.Perft(5) // 4 865 609 for the start position
The traversal uses the same legality rules that govern normal play, but it applies moves through an internal make/unmake path to avoid allocating a new Position at each ply. A position that is checkmate or stalemate returns 0 for any depth greater than 0 (no legal moves to count).
Example ¶
package main
import (
"fmt"
"github.com/corentings/chess/v3"
)
func main() {
pos := chess.StartingPosition()
fmt.Println(pos.Perft(3)) // 8,902 leaf positions at depth 3
}
Output: 8902
func (*Position) PositionKey ¶
PositionKey returns the four FEN fields that identify a position, without the half-move clock and full-move number.
func (*Position) SamePosition ¶
SamePosition returns true if the two positions are the same according to FIDE Article 9.2.3. Uses Zobrist hash as a fast-path, falling back to full field comparison on hash collision.
func (*Position) Status ¶
Status returns the position's outcome Method (e.g. Checkmate, Stalemate, or NoMethod).
func (*Position) String ¶
String implements the fmt.Stringer interface and returns a string with the FEN format: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1.
func (*Position) UnmarshalBinary ¶
UnmarshalBinary implements the encoding.BinaryMarshaler interface.
func (*Position) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface and assumes the data is in the FEN format.
func (*Position) UnsafeMoves ¶
UnsafeMoves returns all pseudo-legal moves that are illegal because they leave the moving side's king in check. These moves should not be played via Move().
func (*Position) Update ¶
Update returns a new position resulting from the given move. The move isn't validated - use Game.Move() for validation. This method is optimized for move generation where validation is handled separately.
Example:
newPos := pos.Update(move)
func (*Position) ValidMoves ¶
ValidMoves returns all legal moves in the current position. The moves are cached for performance. The returned slice is a defensive copy safe for modification by the caller.
func (*Position) ValidMovesIter ¶
ValidMovesIter yields all legal moves in the current position. It uses Go 1.23's range-over-func pattern for zero-allocation iteration once the move cache is warm. The first call may allocate if moves have not been computed yet.
Example:
for move := range pos.ValidMovesIter {
// process move
}
func (*Position) ValidMovesUnsafe ¶
ValidMovesUnsafe returns all legal moves in the current position without copying. The caller must not modify the returned slice. This is a zero-allocation alternative to ValidMoves() for hot paths.
func (*Position) Variant ¶
Variant returns the starting-position variant of the position. The zero value is Standard.
func (*Position) XFENString ¶
XFENString is similar to String() except it uses the legally-relevant en passant square (the square only when an enemy pawn can actually capture) instead of the raw FEN en passant square. For Chess960 positions the castling-rights field is emitted in Shredder-FEN file-letter form. The name is historical: this is the FEN key with clocks, not a separate notation.
func (*Position) ZobristHash ¶
ZobristHash returns the Zobrist hash of the position. This is a fast, collision-resistant hash suitable for transposition tables and position comparison. Two positions that are identical by FIDE rules will have the same hash value.
type RawMoveText ¶
type RawMoveText struct {
// contains filtered or unexported fields
}
RawMoveText is unclassified move data decoded without a board position.
func (RawMoveText) Move ¶
func (m RawMoveText) Move() Move
Move returns the raw move as a Move without legality-derived tags.
func (RawMoveText) Null ¶
func (m RawMoveText) Null() bool
Null reports whether the raw move is a null move.
func (RawMoveText) Promotion ¶
func (m RawMoveText) Promotion() PieceType
Promotion returns the raw promotion piece type.
type Setup ¶
type Setup struct {
Board Board
Turn Color
CastleRights CastleRights
EnPassant Square
HalfMoveClock int
FullMoveNo int
Variant Variant
}
Setup is an unvalidated description of a chess position. It separates "describing a position" from "playing a position" by letting callers build a complete position representation and then asking NewPosition to validate it.
func Chess960Setup ¶
Chess960Setup returns the Setup for the Chess960 starting position with the given Scharnagl index (0-959). The index selects one of 960 initial back-rank arrangements satisfying the Chess960 constraints: bishops on opposite-colored squares and the king placed between the two rooks. Index 518 is the standard starting position. The returned Setup has Variant Chess960 and full castling rights for both sides.
func EmptySetup ¶
func EmptySetup() Setup
EmptySetup returns a Setup representing an empty board: no pieces, White to move, no castling rights, no en passant square, halfmove clock 0, fullmove 1. It is the zero position used as a starting point for construction.
func InitialSetup ¶
func InitialSetup() Setup
InitialSetup returns a Setup representing the standard chess starting position. The returned value is a copy and safe for callers to mutate.
func (Setup) Mirror ¶
Mirror returns a vertically mirrored copy of s: every piece swaps color and moves to the square on the same file but the opposite rank (rank 1 ↔ rank 8); the side to move flips; castling rights swap color; the en passant square moves to the opposite rank. Halfmove clock and fullmove number are preserved.
Useful for opening-book authors who want to reuse one side's analysis for the other, and for symmetric position testing. Mirroring a legal standard position always produces a legal standard position.
func (Setup) SwapTurn ¶
SwapTurn returns a copy of s with the side to move flipped and the en passant square cleared. Halfmove clock and fullmove number are preserved. This is the FIDE "pass" semantic used for repetition detection: only the side to move and en passant rights change, not the move counters.
type Square ¶
type Square int8
A Square is one of the 64 rank and file combinations that make up a chess board.
func ParseSquare ¶
ParseSquare converts a 2-character square notation (e.g., "e4") to a Square. It returns an error if the input is not a valid square.
func SquareFromString
deprecated
type TokenType ¶
type TokenType int
TokenType represents the type of token in PGN text.
const ( EOF TokenType = iota Undefined TagStart // [ TagEnd // ] TagKey // The key part of a tag (e.g., "Site") TagValue // The value part of a tag (e.g., "Internet") MoveNumber // 1, 2, 3, etc. DOT // . ELLIPSIS // ... PIECE // N, B, R, Q, K SQUARE // e4, e5, etc. CommentStart // { CommentEnd // } COMMENT // The comment text RESULT // 1-0, 0-1, 1/2-1/2, * CAPTURE // 'x' in moves FILE // a-h in moves when used as disambiguation RANK // 1-8 in moves when used as disambiguation KingsideCastle // 0-0 QueensideCastle // 0-0-0 PROMOTION // = in moves PromotionPiece // The piece being promoted to (Q, R, B, N) CHECK // + in moves CHECKMATE // # in moves NAG // Numeric Annotation Glyph (e.g., $1, $2, etc.) VariationStart // ( for starting a variation VariationEnd // ) for ending a variation CommandStart // [% CommandName // The command name (e.g., clk, eval) CommandParam // Command parameter CommandEnd // ] DeambiguationSquare // Full square disambiguation (e.g., e8 in Qe8f7) NullMove // A null move: Z0, Z1, --, or @@ )
type Variant ¶
type Variant int8
Variant identifies the starting-position variant of a position. The zero value is Standard. Chess960 (Fischer Random Chess) selects one of 960 indexed initial back-rank arrangements; its castling rights and rook origins differ from standard chess but its castling destinations do not.
Source Files
¶
- attacks.go
- bitboard.go
- bitboard_public.go
- board.go
- castling.go
- doc.go
- errors.go
- fen.go
- framer.go
- game.go
- game_move.go
- game_outcome.go
- game_split.go
- hashes.go
- legality.go
- lexer.go
- magic.go
- move.go
- move_applier.go
- move_text_codec.go
- movegen.go
- movetree.go
- nag.go
- notation.go
- notation_resolver.go
- outcome.go
- outcome_types.go
- patterns.go
- perft.go
- pgn.go
- pgn_decoder.go
- pgn_renderer.go
- piece.go
- polyglot.go
- position.go
- setup.go
- square.go
- stringer.go
- utils.go
- zobrist.go
