Skip to main content

Overview

This module provides types and classes for representing chess position setups, material counts, and castling rights.
import { defaultSetup, Material, Castles } from 'chessops';

const setup = defaultSetup();
const material = Material.fromBoard(setup.board);
console.log('Total pieces:', material.size());

Setup

Represents a complete (not necessarily legal) chess or chess variant position.

Interface

interface Setup {
  board: Board;
  pockets: Material | undefined;
  turn: Color;
  castlingRights: SquareSet;
  epSquare: Square | undefined;
  remainingChecks: RemainingChecks | undefined;
  halfmoves: number;
  fullmoves: number;
}
board
Board
The board with piece positions
pockets
Material | undefined
Pieces in hand (for variants like Crazyhouse). Undefined for standard chess.
turn
Color
The side to move (‘white’ or ‘black’)
castlingRights
SquareSet
Squares of rooks that still have castling rights
epSquare
Square | undefined
The en passant target square, if any
remainingChecks
RemainingChecks | undefined
Remaining checks for Three-Check variant. Undefined for standard chess.
halfmoves
number
Halfmove clock for the fifty-move rule
fullmoves
number
Fullmove number, starting at 1 and incremented after Black’s move

Factory Functions

defaultSetup

defaultSetup(): Setup
Creates a setup with the standard chess starting position.
import { defaultSetup } from 'chessops';

const setup = defaultSetup();
console.log(setup.turn); // 'white'
console.log(setup.fullmoves); // 1

emptySetup

emptySetup(): Setup
Creates a setup with an empty board.
import { emptySetup } from 'chessops';

const setup = emptySetup();
console.log(setup.board.occupied.isEmpty()); // true

Utility Functions

setupClone

setupClone(setup: Setup): Setup
Creates a deep copy of a setup.
setup
Setup
required
The setup to clone
import { setupClone } from 'chessops';

const original = defaultSetup();
const copy = setupClone(original);

// Modifications to copy don't affect original
copy.turn = 'black';
console.log(original.turn); // 'white'

setupEquals

setupEquals(left: Setup, right: Setup): boolean
Compares two setups for equality.
left
Setup
required
First setup to compare
right
Setup
required
Second setup to compare
import { setupEquals, defaultSetup } from 'chessops';

const setup1 = defaultSetup();
const setup2 = defaultSetup();

if (setupEquals(setup1, setup2)) {
  console.log('Setups are identical');
}

MaterialSide

Represents material count for one side.

Properties

pawn
number
Number of pawns
knight
number
Number of knights
bishop
number
Number of bishops
rook
number
Number of rooks
queen
number
Number of queens
king
number
Number of kings

Static Methods

empty

static empty(): MaterialSide
Creates an empty material side with all pieces set to 0.
import { MaterialSide } from 'chessops';

const material = MaterialSide.empty();
console.log(material.pawn); // 0

fromBoard

static fromBoard(board: Board, color: Color): MaterialSide
Creates a material side from a board for the given color.
board
Board
required
The board to count pieces from
color
Color
required
The color to count pieces for
import { MaterialSide, Board } from 'chessops';

const board = Board.default();
const whiteMaterial = MaterialSide.fromBoard(board, 'white');
console.log(whiteMaterial.pawn); // 8

Instance Methods

clone

clone(): MaterialSide
Creates a copy of the material side.
const copy = material.clone();

equals

equals(other: MaterialSide): boolean
Compares two material sides for equality.
other
MaterialSide
required
The other material side to compare
if (material1.equals(material2)) {
  console.log('Same material');
}

add

add(other: MaterialSide): MaterialSide
Adds another material side to this one.
other
MaterialSide
required
The material to add
const total = material1.add(material2);

subtract

subtract(other: MaterialSide): MaterialSide
Subtracts another material side from this one.
other
MaterialSide
required
The material to subtract
const difference = material1.subtract(material2);

size

size(): number
Returns the total number of pieces.
const totalPieces = material.size();

isEmpty

isEmpty(): boolean
Checks if there are no pieces.
if (material.isEmpty()) {
  console.log('No pieces');
}

nonEmpty

nonEmpty(): boolean
Checks if there is at least one piece.
if (material.nonEmpty()) {
  console.log('Has pieces');
}

hasPawns

hasPawns(): boolean
Checks if there are any pawns.
if (material.hasPawns()) {
  console.log('Has pawns');
}

hasNonPawns

hasNonPawns(): boolean
Checks if there are any pieces other than pawns.
if (material.hasNonPawns()) {
  console.log('Has pieces other than pawns');
}

Material

Represents material count for both sides.

Constructor

constructor(white: MaterialSide, black: MaterialSide)
white
MaterialSide
required
Material for white
black
MaterialSide
required
Material for black

Properties

white
MaterialSide
White’s material
black
MaterialSide
Black’s material

Static Methods

empty

static empty(): Material
Creates empty material for both sides.
import { Material } from 'chessops';

const material = Material.empty();

fromBoard

static fromBoard(board: Board): Material
Creates material from a board.
board
Board
required
The board to count pieces from
import { Material, Board } from 'chessops';

const board = Board.default();
const material = Material.fromBoard(board);
console.log('White pawns:', material.white.pawn);
console.log('Black pawns:', material.black.pawn);

Instance Methods

clone

clone(): Material
Creates a copy of the material.
const copy = material.clone();

equals

equals(other: Material): boolean
Compares two materials for equality.
other
Material
required
The other material to compare
if (material1.equals(material2)) {
  console.log('Same material');
}

add

add(other: Material): Material
Adds another material to this one.
other
Material
required
The material to add
const total = material1.add(material2);

subtract

subtract(other: Material): Material
Subtracts another material from this one.
other
Material
required
The material to subtract
const difference = material1.subtract(material2);

count

count(role: Role): number
Returns the total count of a piece role across both colors.
role
Role
required
The piece role to count
const totalQueens = material.count('queen');

size

size(): number
Returns the total number of pieces for both sides.
const totalPieces = material.size();

isEmpty

isEmpty(): boolean
Checks if both sides have no pieces.
if (material.isEmpty()) {
  console.log('No pieces on board');
}

nonEmpty

nonEmpty(): boolean
Checks if at least one side has pieces.
if (material.nonEmpty()) {
  console.log('Has pieces');
}

hasPawns

hasPawns(): boolean
Checks if either side has pawns.
if (material.hasPawns()) {
  console.log('Pawns are present');
}

hasNonPawns

hasNonPawns(): boolean
Checks if either side has pieces other than pawns.
if (material.hasNonPawns()) {
  console.log('Has pieces other than pawns');
}

RemainingChecks

Tracks remaining checks for the Three-Check variant.

Constructor

constructor(white: number, black: number)
white
number
required
Remaining checks for white
black
number
required
Remaining checks for black

Properties

white
number
Number of remaining checks white can give
black
number
Number of remaining checks black can give

Static Methods

default

static default(): RemainingChecks
Creates default remaining checks (3 for each side).
import { RemainingChecks } from 'chessops';

const checks = RemainingChecks.default();
console.log(checks.white); // 3
console.log(checks.black); // 3

Instance Methods

clone

clone(): RemainingChecks
Creates a copy of the remaining checks.
const copy = checks.clone();

equals

equals(other: RemainingChecks): boolean
Compares two remaining checks for equality.
other
RemainingChecks
required
The other remaining checks to compare
if (checks1.equals(checks2)) {
  console.log('Same check counts');
}

Castles

Tracks castling rights and paths.

Properties

castlingRights
SquareSet
Squares of rooks that still have castling rights
rook
ByColor<ByCastlingSide<Square | undefined>>
Rook positions for castling, organized by color and side
path
ByColor<ByCastlingSide<SquareSet>>
Squares that must be empty for castling, organized by color and side

Static Methods

default

static default(): Castles
Creates castles with standard chess castling rights.
import { Castles } from 'chessops/chess';

const castles = Castles.default();
console.log(castles.castlingRights.size()); // 4 (rooks on a1, h1, a8, h8)

empty

static empty(): Castles
Creates castles with no castling rights.
const castles = Castles.empty();
console.log(castles.castlingRights.isEmpty()); // true

fromSetup

static fromSetup(setup: Setup): Castles
Creates castles from a setup, inferring rook positions from castling rights.
setup
Setup
required
The setup to create castles from
import { Castles } from 'chessops/chess';
import { defaultSetup } from 'chessops';

const setup = defaultSetup();
const castles = Castles.fromSetup(setup);

Instance Methods

clone

clone(): Castles
Creates a copy of the castles.
const copy = castles.clone();

discardRook

discardRook(square: Square): void
Removes castling rights for the rook on the given square.
square
Square
required
The square of the rook to discard
castles.discardRook(0); // Remove castling rights for a1

discardColor

discardColor(color: Color): void
Removes all castling rights for the given color.
color
Color
required
The color to remove castling rights for
castles.discardColor('white'); // Remove all white castling rights

Examples

Working with Setups

import { defaultSetup, setupClone } from 'chessops';
import { makeFen } from 'chessops/fen';

const setup = defaultSetup();

// Modify the setup
setup.turn = 'black';
setup.halfmoves = 5;
setup.fullmoves = 3;

// Convert to FEN
const fen = makeFen(setup);
console.log(fen);

// Clone before modifying
const copy = setupClone(setup);
copy.turn = 'white';

Material Analysis

import { Material, Board } from 'chessops';

const board = Board.default();
const material = Material.fromBoard(board);

console.log('White pieces:');
console.log('  Pawns:', material.white.pawn);
console.log('  Knights:', material.white.knight);
console.log('  Bishops:', material.white.bishop);
console.log('  Rooks:', material.white.rook);
console.log('  Queens:', material.white.queen);
console.log('  Kings:', material.white.king);

console.log('Total pieces:', material.size());
console.log('Total queens:', material.count('queen'));

Material Difference

import { Material, Board } from 'chessops';

const board = Board.default();

// Remove some pieces
board.take(8);  // Remove a white pawn
board.take(12); // Remove another white pawn

const current = Material.fromBoard(board);
const starting = Material.fromBoard(Board.default());

const difference = starting.subtract(current);
console.log('Captured white pawns:', difference.white.pawn);

Castling Rights Management

import { Castles } from 'chessops/chess';
import { defaultSetup } from 'chessops';

const castles = Castles.fromSetup(defaultSetup());

console.log('White can castle queenside:', castles.rook.white.a !== undefined);
console.log('White can castle kingside:', castles.rook.white.h !== undefined);

// Remove castling right when king moves
castles.discardColor('white');

console.log('White castling rights:', castles.rook.white.a); // undefined

Three-Check Variant

import { RemainingChecks } from 'chessops';

const checks = RemainingChecks.default();

// After white gives a check
checks.white = Math.max(checks.white - 1, 0);

console.log('White remaining checks:', checks.white);

if (checks.white === 0) {
  console.log('White wins by three checks!');
}

Build docs developers (and LLMs) love