Position class and inherit its methods. Each variant implements specific rule modifications.
Crazyhouse
Crazyhouse is a variant where captured pieces can be dropped back onto the board.Key Differences from Chess
- Captured pieces go into the captor’s pocket
- Pieces can be dropped on empty squares instead of moving
- Promoted pieces demote to pawns when captured
- Pawns cannot be dropped on the first or eighth rank
Static Methods
Crazyhouse.default()
Creates a new Crazyhouse position with the standard starting position.A new Crazyhouse position in the starting state with empty pockets
Crazyhouse.fromSetup(setup)
Creates a Crazyhouse position from a Setup object.The position setup including optional pockets
A Result containing either the valid Crazyhouse position or a PositionError
Instance Methods
clone()
A deep copy of the Crazyhouse position
dropDests(ctx?)
Computes legal squares for dropping pieces from the pocket.Optional pre-computed context
Set of legal drop squares:
- All empty squares for non-pawns
- Empty squares excluding first/eighth ranks for pawns
- If in check, only squares that block the check
hasInsufficientMaterial(color)
Crazyhouse-specific insufficient material check.The color to check
true only if total pieces (board + pockets) ≤ 3 and no pawns/rooks/queens existPlaying Drops
Atomic
In Atomic chess, captures cause explosions that destroy surrounding pieces (except pawns).Key Differences from Chess
- Captures explode the capturing piece, captured piece, and all non-pawn pieces on adjacent squares
- Kings cannot capture or be adjacent to each other
- Exploding the opponent’s king wins immediately
- Your own king can be missing (already exploded)
Static Methods
Atomic.default()
A new Atomic position in the standard starting state
Atomic.fromSetup(setup)
The position setup
A Result containing either the valid Atomic position or a PositionError
Instance Methods
clone()
A deep copy of the Atomic position
kingAttackers(square, attacker, occupied)
Atomic-specific attack detection that prevents kings from attacking.The square being attacked
The attacking color
The set of occupied squares
Set of pieces attacking the square (empty if attacker’s king is adjacent, since kings cannot capture)
dests(square, ctx?)
Computes legal moves with Atomic explosion rules.Legal moves excluding those that would expose your own king to explosion
hasInsufficientMaterial(color)
Atomic-specific insufficient material rules.false if opponent’s king is exploded or if side has enough material to force explosionsisVariantEnd()
true if either king has been explodedvariantOutcome(ctx?)
{ winner: Color } if opponent’s king exploded, otherwise undefinedAntichess
In Antichess (also called Losing Chess), the goal is to lose all your pieces or be stalemated.Key Differences from Chess
- Captures are mandatory (must capture if possible)
- Kings are normal pieces (no check, checkmate, or castling)
- Winning condition: lose all pieces or get stalemated
- Pawns can promote to kings
Static Methods
Antichess.default()
A new Antichess position (no castling rights)
Antichess.fromSetup(setup)
The position setup
A Result containing either the valid Antichess position or a PositionError
Instance Methods
clone()
A deep copy of the Antichess position
kingAttackers(square, attacker, occupied)
Always returns an empty set (no check in Antichess)
ctx()
Computes context including mandatory capture detection.Context with
mustCapture: true if any capture is availabledests(square, ctx?)
Computes legal moves, restricting to captures if mandatory.Only capture moves if
ctx.mustCapture is true, otherwise all pseudo-legal moveshasInsufficientMaterial(color)
Antichess-specific insufficient material (very complex due to inverted goal).true if the side cannot force losing all piecesisVariantEnd()
true if the current player has no pieces leftvariantOutcome(ctx?)
{ winner: currentPlayer } if they have no pieces or are stalematedKing of the Hill
Win by getting your king to one of the four center squares.Key Differences from Chess
- Win condition: king reaches d4, e4, d5, or e5
- No insufficient material draws (king can always reach center)
Static Methods
KingOfTheHill.default()
A new King of the Hill position
KingOfTheHill.fromSetup(setup)
The position setup
A Result containing either the valid King of the Hill position or a PositionError
Instance Methods
clone()
A deep copy of the King of the Hill position
hasInsufficientMaterial(color)
Always returns
false (king can always try to reach center)isVariantEnd()
true if any king is on a center square (d4, e4, d5, e5)variantOutcome(ctx?)
{ winner: Color } if that color’s king is on a center squareThree-Check
Win by checking the opponent’s king three times.Key Differences from Chess
- Each check is counted and tracked
- Win condition: give check 3 times or checkmate
- Insufficient material: only bare king
Static Methods
ThreeCheck.default()
A new Three-Check position with 3 remaining checks for each side
ThreeCheck.fromSetup(setup)
The position setup including optional remainingChecks
A Result containing either the valid Three-Check position or a PositionError
Instance Methods
clone()
A deep copy of the Three-Check position
hasInsufficientMaterial(color)
true only if the side has only a king (cannot give check)isVariantEnd()
true if either side has 0 remaining checksvariantOutcome(ctx?)
{ winner: Color } if that color has given 3 checksTracking Checks
Checks are automatically decremented whenplay() is called:
Racing Kings
Both sides race to get their king to the eighth rank. No checks allowed.Key Differences from Chess
- Custom starting position (both sides start on ranks 1-2)
- No pawns in starting position
- Cannot give check
- Win condition: king reaches rank 8 first
- If white reaches rank 8, black gets one more move to tie
- No castling
Static Methods
RacingKings.default()
A new Racing Kings position with the standard starting layout
RacingKings.fromSetup(setup)
The position setup (must not have pawns or checks)
A Result containing either the valid Racing Kings position or a PositionError
Instance Methods
clone()
A deep copy of the Racing Kings position
dests(square, ctx?)
Computes legal moves excluding moves that give check.Legal moves that don’t put the opponent in check
hasInsufficientMaterial(color)
Always returns
false (king can always race to rank 8)isVariantEnd()
true if a king has reached rank 8, considering black’s catch-up opportunityvariantOutcome(ctx?)
{ winner: 'white' }if only white reached rank 8{ winner: 'black' }if only black reached rank 8{ winner: undefined }if both reached rank 8 (draw)undefinedif game continues
Horde
White has a horde of pawns instead of regular pieces. Black plays normally.Key Differences from Chess
- Custom starting position: White has 36 pawns, black has normal pieces
- White has no king
- White wins by capturing all black pieces
- Black wins by capturing all white pieces or checkmating the white king (if custom position)
- White cannot castle (no king)
- Complex insufficient material rules
Static Methods
Horde.default()
A new Horde position with the standard starting layout (36 white pawns vs normal black pieces)
Horde.fromSetup(setup)
The position setup (must have exactly 0 or 1 kings total)
A Result containing either the valid Horde position or a PositionError
Instance Methods
clone()
A deep copy of the Horde position
hasInsufficientMaterial(color)
Extremely complex insufficient material rules specific to Horde.The color to check
false if the side with the king can capture the hordeFor the horde side (no king), analyzes complex mating patterns based on:- Number of pieces in the horde
- Piece types and square colors
- Opponent’s pieces and their configuration
isVariantEnd()
true if either white or black has no pieces leftvariantOutcome(ctx?)
{ winner: 'black' }if white (horde) has no pieces{ winner: 'white' }if black has no piecesundefinedif game continues
Utility Functions
defaultPosition(rules)
Creates a default position for any variant.The variant rules:
'chess', 'atomic', 'crazyhouse', 'antichess', 'kingofthehill', '3check', 'racingkings', 'horde'A new position in the default starting state for the variant
setupPosition(rules, setup)
Creates a position from a setup for any variant.The variant rules
The position setup to load
A Result containing either the valid position or a PositionError
isStandardMaterial(pos)
Checks if a position has standard material for its variant.The position to check
true if the material is standard for the variant:- Chess/Atomic/Antichess/King of the Hill/Three-Check: No promoted pieces beyond starting material
- Crazyhouse: Accounts for promoted pieces and pockets
- Horde: White ≤ 36 pieces, black has standard material if they have a king
- Racing Kings: Each side has ≤ 2 rooks, 2 bishops, 2 knights, 1 queen
Variant Comparison
| Variant | Starting Position | Win Condition | Special Rules |
|---|---|---|---|
| Chess | Standard | Checkmate | Castling, en passant |
| Crazyhouse | Standard | Checkmate | Drop captured pieces |
| Atomic | Standard | King explosion | Captures explode |
| Antichess | Standard | Lose all pieces | Mandatory captures, no check |
| King of the Hill | Standard | King to center | Reach d4/e4/d5/e5 |
| Three-Check | Standard | 3 checks or checkmate | Count checks |
| Racing Kings | Custom (no pawns) | King to rank 8 | No checks allowed |
| Horde | Custom (36 white pawns) | Capture all pieces | White has no king |