Draughts

Thirteen draughts variants with forced-capture chains, flying kings, a minimax opponent, and embed support.

Embed via iframe

<iframe
  src="https://engine.moddable.games/play/?embed=1&family=draughts&variant=international"
  style="width:100%;max-width:560px;aspect-ratio:1/1;border:none"
  title="Play Draughts"
></iframe>

The parameters, commands and events are identical to every other family. See the Go page for the full table; substitute family=draughts.

Variants

Parameters follow the draughts hub in moddable-rules.

KeyBoardDistinguishing rule
english8×8Men capture forwards only, kings do not fly
international10×10Flying kings, longest capture chain compulsory
brazilian8×8International rules on the small board
canadian12×12International rules, thirty pieces a side
russian8×8Backward capture, mid-jump promotion, free choice
pool8×8Russian rules, the US tournament standard
german8×8Capture in all directions, no majority rule
spanish8×8Majority rule, ties resolved in favour of the king
czech8×8King captures take priority over man captures
italian8×8Men may not capture kings
turkish-draughts8×8Orthogonal movement across all sixty-four squares
ghanaian10×10Reduced to one piece is a loss
spantsiretti10×8Russian rules on a wider board

Capture chains

A multi-jump is a sequence of moves, not one move. The plugin signals continueTurn after each jump, so the turn does not advance and the controller anchors selection to the jumping piece until the chain is exhausted.

ctrl.handleClick(from)        // select
ctrl.handleClick(firstJump)   // capture, turn does not pass
ctrl.getState().chainAnchor   // the piece mid-chain
ctrl.handleClick(secondJump)  // continue the same chain

While a chain is live the interaction model rejects clicks that would abandon it. Board state and turn order stay consistent because the core move pipeline, not the interface, owns the decision.

Variant parameters

Every variant above is expressed through the plugin's parametric configuration, with no per-variant code:

ParameterEffect
directionsdiagonal or orthogonal movement and capture
manCaptureforward or all
forcedCaptureCaptures are compulsory when available
maximalCaptureThe longest available chain must be taken
majorityPrefersKingTies in chain length resolve to the king's capture
kingCapturePriorityAny king capture outranks any man capture
menCannotCaptureKingsMen may not jump kings
flyingKingsKings slide any distance along a line
promotionDuringPromotion mid-chain continues as a king
removeImmediatelyCaptured pieces leave after each jump, not at the end
loseOnSinglePieceBeing reduced to one piece is a loss

SDK

The SDK is the same across every family; only the family key and the shape of a move differ.

import { createGame, getLegalMoves, getGameStatus, createAI, listVariants } from 'moddable-engine/play'

listVariants('draughts')                 // [{ key, label, group, board, description }]
const game = createGame('draughts', 'international')
game.getLegalMoves()                     // [{ from, to, captures: [...] }, ...]
game.applyMove({ from: 31, to: 22 })
getGameStatus('draughts', 'international', game.getState())

const ai = createAI('draughts', 'international', { difficulty: 'hard' })
ai.pickMove(game.getState().slice, 0)    // minimax by default for draughts

Difficulty accepts beginner, easy, medium, hard and expert.

Because captures are compulsory in most variants, getLegalMoves already reflects the forced-capture and maximal-capture parameters — a quiet move simply will not be in the list when a capture is available. A multi-jump arrives as a sequence of separate moves rather than one move; see capture chains above, and drive it through the chain interaction model:

import { interactionModelFor } from 'moddable-engine/play'

const model = interactionModelFor('draughts')   // the 'chain' model
model.handleClick(pos, ctx)                     // rejects clicks that abandon a live chain

Known gaps

Seven hub variants are not registered, each because it needs a mechanic the plugin does not model:

Each is named in UNSUPPORTED in the variant module with its reason, so the gap is visible in code rather than silently missing.