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 |
|---|---|---|---|---|
|
10×10 |
Yes |
Required |
Alias for StandardBoard |
|
10×10 |
Yes |
Required |
International draughts |
|
8×8 |
No |
Not required |
English checkers |
|
10×10 |
Yes |
Required |
Orthogonal captures allowed |
|
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
Legal Moves
board = Board()
# Get all legal moves
moves = board.legal_moves
print(len(moves)) # 9 in starting position
# Check if a move is a capture
for move in board.legal_moves:
if move.captured_list:
print(f"{move} captures {len(move.captured_list)} pieces")
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.WHITEorColor.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
Moveobjects 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
Moveto apply. is_finished: If True, switches turn after the move. Set to Falseduring 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
Movethat 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.
- str_move: Move in UCI format, e.g.
- 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_COUNTwith 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