chego

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2025 License: MPL-2.0 Imports: 4 Imported by: 0

README

Go Reference

Chego implements chessboard state management and legal move generation.

Piece positions are stored as bitboards.

Move generation is implemented using the Magic Bitboards method.

It is assigned to use in the web-servers (for example, justchess.org),
hence it does not provide any GUI or CLI.

Usage

To install chego, run go get:

go get github.com/treepeck/chego

Here is a simple example:

package main

import (
	"fmt"

	"github.com/treepeck/chego"
)

func main() {
	// It is important to call InitAttackTables as close to the program
	// start as possible, otherwise the move generation won't work.
	chego.InitAttackTables()

	g := chego.NewGame()
	// Scholar's mate.
	g.PushMove(chego.NewMove(chego.SF3, chego.SF2, chego.MoveNormal))
	g.PushMove(chego.NewMove(chego.SE5, chego.SE7, chego.MoveNormal))
	g.PushMove(chego.NewMove(chego.SG4, chego.SG2, chego.MoveNormal))
	g.PushMove(chego.NewMove(chego.SH4, chego.SD8, chego.MoveNormal))
 	// Prints "Is checkmate: true"
	fmt.Printf("Is checkmate: %t\n", g.IsCheckmate())
}

Local installation

First install the Go compiler version 1.24.1 or newer (see https://go.dev/dl).

Once the compiler is installed, clone this repository:

git clone https://github.com/treepeck/chego
cd chego

Tests and benchmarks

To execute the performance test, run this command in the chego folder:

go run ./internal/perft.go -depth {IntValue}

Chego generates 119060324 moves at depth 6 in approximately 6 seconds
on an Intel i7-10750H CPU.

License

Copyright (c) 2025 Artem Bielikov

This project is available under the Mozilla Public License, v. 2.0.
See the LICENSE file for details.

Documentation

Index

Constants

View Source
const (
	// Bitmask of all files except the A.
	NOT_A_FILE uint64 = 0xFEFEFEFEFEFEFEFE
	// Bitmask of all files except the H.
	NOT_H_FILE uint64 = 0x7F7F7F7F7F7F7F7F
	// Bitmask of all files except the A and B.
	NOT_AB_FILE uint64 = 0xFCFCFCFCFCFCFCFC
	// Bitmask of all files except the G and H.
	NOT_GH_FILE uint64 = 0x3F3F3F3F3F3F3F3F
	// Bitmask of all ranks except first.
	NOT_1ST_RANK uint64 = 0xFFFFFFFFFFFFFF00
	// Bitmask of all ranks except eighth.
	NOT_8TH_RANK uint64 = 0x00FFFFFFFFFFFFFF
	// Bitmask of the first rank.
	RANK_1 uint64 = 0xFF
	// Bitmask of the second rank.
	RANK_2 uint64 = 0xFF00
	// Bitmask of the seventh rank.
	RANK_7 uint64 = 0xFF000000000000
	// Bitmask of the eighth rank.
	RANK_8 uint64 = 0xFF00000000000000
)
View Source
const (
	A1 uint64 = 1 << iota
	B1
	C1
	D1
	E1
	F1
	G1
	H1
	A2
	B2
	C2
	D2
	E2
	F2
	G2
	H2
	A3
	B3
	C3
	D3
	E3
	F3
	G3
	H3
	A4
	B4
	C4
	D4
	E4
	F4
	G4
	H4
	A5
	B5
	C5
	D5
	E5
	F5
	G5
	H5
	A6
	B6
	C6
	D6
	E6
	F6
	G6
	H6
	A7
	B7
	C7
	D7
	E7
	F7
	G7
	H7
	A8
	B8
	C8
	D8
	E8
	F8
	G8
	H8
	ALL_SQUARES = 0xFFFFFFFFFFFFFFFF
)

Bitboards of each square.

View Source
const (
	SA1 int = iota
	SB1
	SC1
	SD1
	SE1
	SF1
	SG1
	SH1
	SA2
	SB2
	SC2
	SD2
	SE2
	SF2
	SG2
	SH2
	SA3
	SB3
	SC3
	SD3
	SE3
	SF3
	SG3
	SH3
	SA4
	SB4
	SC4
	SD4
	SE4
	SF4
	SG4
	SH4
	SA5
	SB5
	SC5
	SD5
	SE5
	SF5
	SG5
	SH5
	SA6
	SB6
	SC6
	SD6
	SE6
	SF6
	SG6
	SH6
	SA7
	SB7
	SC7
	SD7
	SE7
	SF7
	SG7
	SH7
	SA8
	SB8
	SC8
	SD8
	SE8
	SF8
	SG8
	SH8
)

Indicies of each square.

View Source
const InitialPos = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

Variables

View Source
var (
	// PieceSymbols maps each piece type to its symbol.
	PieceSymbols = [12]byte{
		'P', 'p', 'N', 'n', 'B', 'b',
		'R', 'r', 'Q', 'q', 'K', 'k',
	}
	// Square2String maps each board square to its string representation.
	Square2String = [64]string{
		"a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1",
		"a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
		"a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
		"a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
		"a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
		"a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
		"a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
		"a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8",
	}
)

Functions

func CountBits

func CountBits(bitboard uint64) (cnt int)

CountBits returns the number of bits set within the bitboard.

func GenChecksCounter

func GenChecksCounter(bitboards [15]uint64, c Color) (cnt int)

GenChecksCounter returns the number of the pieces of the specified color that are delivering a check to the enemy king.

func GenLegalMoves

func GenLegalMoves(p Position, l *MoveList)

GenLegalMoves generates legal moves for the given position using copy-make approach.

func InitAttackTables

func InitAttackTables()

InitAttackTables initializes the predefined attack tables. Call this function ONCE as close as possible to the start of your program.

NOTE: Move generation will not work if the attack tables are not initialized.

func InitZobristKeys

func InitZobristKeys()

InitZobristKeys initializes the pseudo-random keys used in the Zobrist hashing scheme. Call this function ONCE as close as possible to the start of your program.

NOTE: Threefold repetitions will not be detected if this funtcion wasn't called.

func Move2UCI

func Move2UCI(m Move) string

Move2UCI converts the move into a long algebraic notation string.

Examples: e2e4, e7e5, e1g1 (white short castling), e7e8q (for promotion).

func ParseBitboards

func ParseBitboards(piecePlacement string) (bitboards [15]uint64)

ParseBitboards converts the first part of a FEN string into an array of bitboards. May panic if the provided string is not valid.

func SerializeBitboards

func SerializeBitboards(bitboards [15]uint64) string

SerializeBitboards converts the array of bitboards into the first part of FEN string.

func SerializeFEN

func SerializeFEN(p Position) string

SerializeFEN serializes the specified Position into a FEN string.

Types

type CastlingRights

type CastlingRights = int

CastlingRights defines the player's rights to perform castlings.

  • 0 bit: white king can O-O.
  • 1 bit: white king can O-O-O.
  • 2 bit: black king can O-O.
  • 3 bit: black king can O-O-O.
const (
	CastlingWhiteShort CastlingRights = 1
	CastlingWhiteLong  CastlingRights = 2
	CastlingBlackShort CastlingRights = 4
	CastlingBlackLong  CastlingRights = 8
)

type Color

type Color = int

Color is an allias type to avoid bothersome conversion between int and Color.

const (
	ColorWhite Color = iota
	ColorBlack
	ColorBoth
)

type CompletedMove

type CompletedMove struct {
	// Board state after completing the move to enable move undo and
	// state restoration.
	FenString string
	// Move itself.
	Move Move
	// Remaining time on a player's clock in seconds.
	TimeLeft int
}

CompletedMove represents a completed move.

type Game

type Game struct {
	LegalMoves MoveList
	Position   Position
	MoveStack  []CompletedMove
	// Keep track of all captured pieces.
	Captured []Piece
	// Keep track of all repeated Zobrist keys to detect
	// a threefold repetition.
	Repetitions map[uint64]int
	// Remaining time on a white player's clock in seconds.  0 by default.
	WhiteTime int
	// Remaining time on a black player's clock in seconds.  0 by default.
	BlackTime int
	// Number of seconds added to player's clock after completing a move.
	TimeBonus int
	// Clock will send a tick signal every second.  By default the Clock is
	// stopped.  The caller should call SetClock to apply the time limit
	// for a game.
	Clock  *time.Ticker
	Result Result
}

Game represents a single chess game state.

Make sure to call InitAttackTables and InitZobristKeys ONCE before creating a Game.

func NewGame

func NewGame() *Game

NewGame creates a new game initialized with the default chess position. Generates legal moves.

func (*Game) IsCheckmate

func (g *Game) IsCheckmate() bool

IsCheckmate returns true if one of the following statements is true:

  • There are no legal moves available for the current turn.
  • The king of the side to move is in check.

NOTE: If there are no legal moves, but the king is not in check, the position is a stalemate.

func (*Game) IsInsufficientMaterial

func (g *Game) IsInsufficientMaterial() bool

IsInsufficientMaterial returns true if one of the following statements is true:

  • Both sides have a bare king.
  • One side has a king and a minor piece against a bare king.
  • Both sides have a king and a bishop, the bishops standing on the same color.
  • Both sides have a king and a knight.

func (*Game) IsMoveLegal

func (g *Game) IsMoveLegal(m Move) bool

IsMoveLegal checks if the specified move is legal.

func (*Game) IsThreefoldRepetition

func (g *Game) IsThreefoldRepetition() bool

IsThreefoldRepetition checks whether the game has reached a threefold repetition.

A position is considered identical if all of the following conditions are met:

  • Active colors are the same.
  • Pieces occupy the same squares.
  • Legal moves are the same.
  • Castling rights are identical.

NOTE: Positions are identical even if the en passant target square differs, provided that no en passant capture is possible.

func (*Game) PopMove

func (g *Game) PopMove()

PopMove pops the last completed move and restores the game state. If there are no completed moves, this function is no-op.

func (*Game) PushMove

func (g *Game) PushMove(m Move)

PushMove updates the game state by performing the specified move. It is a caller responsibility to check if the specified move is legal. Generates legal moves for the next turn.

func (*Game) SetClock

func (g *Game) SetClock(timeControl, timeBonus int)

SetClock initializes each player’s clock with timeControl and starts it. After every completed move, timeBonus seconds are added to the player’s clock.

func (*Game) TimeTick

func (g *Game) TimeTick()

TimeTick decrements the clock value of the currently active player in response to ticks from the [Clock]. It is the caller's responsibility to listen to tick events and end the game if one of the players runs out of time.

type Move

type Move uint16

Move represents a chess move, encoded as a 16 bit unsigned integer:

  • 0-5: To (destination) square index.
  • 6-11: From (origin/source) square index.
  • 12-13: Promotion piece (see PromotionFlag).
  • 14-15: Move type (see MoveType).

func NewMove

func NewMove(to, from, moveType int) Move

NewMove creates a new move with the promotion piece set to PromotionQueen.

func NewPromotionMove

func NewPromotionMove(to, from, promoPiece int) Move

NewPromotionMove creates a new move with the promotion type and specified promotion piece.

func (Move) From

func (m Move) From() int

func (Move) PromoPiece

func (m Move) PromoPiece() PromotionFlag

func (Move) To

func (m Move) To() int

func (Move) Type

func (m Move) Type() MoveType

type MoveList

type MoveList struct {
	// Maximum number of moves per chess position is equal to 218,
	// hence 218 elements.
	// See https://www.talkchess.com/forum/viewtopic.php?t=61792
	Moves [218]Move
	// To keep track of the next move index.
	LastMoveIndex byte
}

MoveList is used to store moves. The main idea behind it is to preallocate an array with enough capacity to store all possible moves and avoid dynamic memory allocations.

func (*MoveList) Push

func (l *MoveList) Push(m Move)

Push adds the move to the end of the move list.

type MoveType

type MoveType = int

MoveType is an allias type to avoid bothersome conversion between int and MoveType.

const (
	// Quite & capture moves.
	MoveNormal MoveType = iota
	// King & queen castling.
	MoveCastling
	// Knight & Bishop & Rook & Queen promotions.
	MovePromotion
	// Special pawn move.
	MoveEnPassant
)

type Piece

type Piece = int

Piece is an allias type to avoid bothersome conversion between int and Piece.

const (
	PieceWPawn Piece = iota
	PieceBPawn
	PieceWKnight
	PieceBKnight
	PieceWBishop
	PieceBBishop
	PieceWRook
	PieceBRook
	PieceWQueen
	PieceBQueen
	PieceWKing
	PieceBKing
	// To avoid magic numbers.
	PieceNone = -1
)

type Position

type Position struct {
	Bitboards      [15]uint64
	ActiveColor    Color
	CastlingRights CastlingRights
	EPTarget       int
	HalfmoveCnt    int
	FullmoveCnt    int
}

Position represents a chessboard state that can be converted to or parsed from a FEN string.

func ParseFEN

func ParseFEN(fen string) (p Position)

ParseFEN parses the given FEN string into a Position. It's a caller's responsibility to validate the provided FEN string.

func (*Position) GetPieceFromSquare

func (p *Position) GetPieceFromSquare(square uint64) Piece

GetPieceFromSquare returns the type of the piece that stands on the specified square, or PieceNone if the square is empty.

func (*Position) MakeMove

func (p *Position) MakeMove(m Move)

MakeMove modifies the position by applying the specified move. It is the caller’s responsibility to check if the specified move is at least pseudo-legal.

Not only is the piece placement updated, but also the entire position, including castling rights, en passant target, halfmove counter, fullmove counter, and the active color.

type PromotionFlag

type PromotionFlag = int

PromotionFlag is an allias type to avoid bothersome conversion between int and Color.

const (
	PromotionKnight PromotionFlag = iota
	PromotionBishop
	PromotionRook
	PromotionQueen
)

00 - knight, 01 - bishop, 10 - rook, 11 - queen.

type Result

type Result int

Result represents the possible outcomes of a chess game.

const (
	ResultUnscored Result = iota // Default value: the game isn't finished yet.
	ResultCheckmate
	ResultTimeout
	ResultStalemate
	ResultInsufficientMaterial
	ResultFiftyMove
	ResultThreefoldRepetition
	ResultResignation
	ResultDrawByAgreement
)

Directories

Path Synopsis
Package main provides debugging and testing functions.
Package main provides debugging and testing functions.

Jump to

Keyboard shortcuts

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