Core API

Quick Start

from draughts import Board

board = Board()                    # Standard 10×10 board
board.push_uci("31-27")            # Make a move
print(board.legal_moves)           # Get legal moves
board.pop()                        # Undo move

Board Classes

Class

Size

Flying Kings

Max Capture

Description

Board

10×10

Yes

Required

Alias for StandardBoard

StandardBoard

10×10

Yes

Required

International draughts

AmericanBoard

8×8

No

Not required

English checkers

FrisianBoard

10×10

Yes

Required

Orthogonal captures allowed

RussianBoard

8×8

Yes

Not required

Flying kings, free capture

from draughts import Board, StandardBoard, AmericanBoard, RussianBoard

board = Board()           # Same as StandardBoard()
board = AmericanBoard()   # 8×8 English checkers
board = RussianBoard()    # 8×8 Russian draughts

Making Moves

board = Board()

# Push move using UCI notation
board.push_uci("31-27")
board.push_uci("18-22")
board.push_uci("27x18")   # Capture notation

# Push a Move object
move = board.legal_moves[0]
board.push(move)

# Undo moves
last_move = board.pop()   # Returns the undone Move

Game State

board = Board()

board.turn                    # Color.WHITE or Color.BLACK
board.game_over               # True if game ended
board.is_draw                 # True if drawn
board.is_threefold_repetition # True if position repeated 3x
board.result                  # "1-0", "0-1", "1/2-1/2", or "-"

FEN Notation

FEN represents board positions. Format: [Turn]:[White pieces]:[Black pieces]

board = Board()

# Get FEN
print(board.fen)
# '[FEN "W:W:W31,32,...,50:B1,2,...,20"]'

# Create from FEN (kings prefixed with K)
board = Board.from_fen("W:WK10,K20:BK35,K45")

PDN Notation

PDN records game moves, similar to PGN in chess.

board = Board()
board.push_uci("32-28")
board.push_uci("18-23")

# Get PDN
print(board.pdn)
# [GameType "20"]
# [Variant "Standard (international) checkers"]
# [Result "-"]
# 1. 32-28 18-23

# Create from PDN
pdn = '[GameType "20"]\n1. 32-28 19-23 2. 28x19 14x23'
board = Board.from_pdn(pdn)

Board Position

board = Board()

# Get position as numpy array
pos = board.position  # Shape: (50,) for standard board
# Values: 1=black man, 2=black king, -1=white man, -2=white king, 0=empty

# Access individual squares (0-indexed)
piece = board[30]  # Square 31

# ASCII representation
print(board)

Square Numbering

Only dark squares are playable. Squares are numbered 1-50 (standard) or 1-32 (american/russian).

Standard Board (10×10)

   1   2   3   4   5
 6   7   8   9  10
  11  12  13  14  15
16  17  18  19  20
  21  22  23  24  25
26  27  28  29  30
  31  32  33  34  35
36  37  38  39  40
  41  42  43  44  45
46  47  48  49  50

American/Russian Board (8×8)

   1   2   3   4
 5   6   7   8
   9  10  11  12
13  14  15  16
  17  18  19  20
21  22  23  24
  25  26  27  28
29  30  31  32

Types Reference

Color

draughts.Color.WHITE = -1
draughts.Color.BLACK = 1

Figure

draughts.Figure.WHITE_MAN = -1
draughts.Figure.WHITE_KING = -2
draughts.Figure.BLACK_MAN = 1
draughts.Figure.BLACK_KING = 2
draughts.Figure.EMPTY = 0

Move

move = board.legal_moves[0]

move.square_list      # [30, 26] - squares visited (0-indexed)
move.captured_list    # [] or [22] - captured squares
move.is_promotion     # True if promotes to king
str(move)             # "31-27" or "26x17"

API Reference

BaseBoard

class draughts.boards.base.BaseBoard(starting_position: ndarray | None = None, turn: Color | None = None)[source]

Abstract base class for all draughts board variants.

Uses bitboard representation for efficient move generation. Board state is stored as four integers: white_men, white_kings, black_men, black_kings.

Attributes:

turn: Current side to move (Color.WHITE or Color.BLACK). halfmove_clock: Moves since last capture or man move (for draw detection). shape: Board dimensions as tuple, e.g. (10, 10) for standard.

Example:
>>> from draughts import Board
>>> board = Board()
>>> board.push_uci("31-27")
>>> print(board.turn)
Color.BLACK
abstract property legal_moves: list[Move]

All legal moves for the current player.

Returns:

List of Move objects representing all legal moves.

Example:
>>> board = Board()
>>> moves = board.legal_moves
>>> print(len(moves))  # 9 moves in starting position
9
abstract property is_draw: bool

Check if the current position is a draw.

Draw conditions vary by variant (e.g., 25-move rule, threefold repetition).

Returns:

True if the position is drawn, False otherwise.

push(move: Move, is_finished: bool = True) None[source]

Apply a move to the board.

Args:

move: The Move to apply. is_finished: If True, switches turn after the move. Set to False

during internal move generation.

Example:
>>> board = Board()
>>> move = board.legal_moves[0]
>>> board.push(move)
pop(is_finished: bool = True) Move[source]

Undo the last move.

Args:
is_finished: If True, switches turn back. Set to False during

internal move generation.

Returns:

The Move that was undone.

Raises:

IndexError: If no moves have been made.

Example:
>>> board = Board()
>>> board.push_uci("31-27")
>>> board.pop()
Move: 31->27
push_uci(str_move: str) None[source]

Make a move using UCI notation.

Args:
str_move: Move in UCI format, e.g. "31-27" for quiet moves

or "26x17" for captures.

Raises:

ValueError: If the move is not legal in the current position.

Example:
>>> board = Board()
>>> board.push_uci("31-27")
>>> board.push_uci("18-22")
property is_threefold_repetition: bool

Check for threefold repetition draw.

Returns:

True if the same position has occurred three times.

property game_over: bool

Check if the game has ended.

Returns:

True if drawn or if the current player has no legal moves.

property result: Literal['1/2-1/2', '1-0', '0-1', '-']

Get the game result.

Returns:
  • "1-0": White wins

  • "0-1": Black wins

  • "1/2-1/2": Draw

  • "-": Game ongoing

static is_capture(move: Move) bool[source]

Check if a move is a capture.

Args:

move: The move to check.

Returns:

True if the move captures at least one piece.

property fen: str

Get the FEN string for the current position.

Returns:

FEN string, e.g. '[FEN "W:W31,32:B1,2"]'. Kings are prefixed with ‘K’.

Example:
>>> board = Board()
>>> print(board.fen)
classmethod from_fen(fen: str) BaseBoard[source]

Create a board from a FEN string.

Args:

fen: FEN string, e.g. "W:W31,32:B1,2" or "W:WK10,K20:BK35,K45".

Returns:

New board instance with the specified position.

Raises:

ValueError: If the FEN string is invalid.

Example:
>>> board = Board.from_fen("W:WK10,K20:BK35,K45")
property pdn: str

Get the PDN string for the game so far.

Returns:

PDN string with headers and move list.

Example:
>>> board = Board()
>>> board.push_uci("31-27")
>>> print(board.pdn)
classmethod from_pdn(pdn: str) BaseBoard[source]

Create a board by replaying moves from a PDN string.

Supports both numeric (e.g., ‘33-28’) and algebraic (e.g., ‘c3-d4’) notation.

Args:

pdn: PDN string with optional headers and move list.

Returns:

Board with all moves from the PDN applied.

Raises:

ValueError: If a move in the PDN is illegal.

Example:
>>> pdn = '[GameType "20"]\n1. 32-28 19-23'
>>> board = Board.from_pdn(pdn)
property position: ndarray

Get the board as a numpy array.

Returns:

1D numpy array of length SQUARES_COUNT with piece values: 1=black man, 2=black king, -1=white man, -2=white king, 0=empty.

Example:
>>> board = Board()
>>> pos = board.position
>>> print(pos.shape)  # (50,) for standard board