Skip to content

API Reference

Board and moves

dame.Board

A draughts board: the start position plus the moves played from it.

Squares are numbered 1 to 50; White starts on 31-50 and moves first. The board enforces the rules: captures are mandatory, the maximum capture must be taken, and games end by the FMJD rules.

Parameters:

Name Type Description Default
fen str | None

The start position in FEN notation, e.g. "W:W31-50:B1-20". Defaults to the standard starting position.

None

Raises:

Type Description
ValueError

If fen is not a valid position.

Examples:

>>> board = Board()
>>> board.push("32-28")
Move('32-28')
>>> board.push("19-23")
Move('19-23')
>>> board.legal_moves
[Move('28x19x23')]

legal_moves property

legal_moves: list[Move]

The legal moves; empty once the game is over.

move_stack property

move_stack: list[Move]

The moves played so far.

must_capture property

must_capture: bool

Whether the side to move has to capture.

ply property

ply: int

The number of moves played so far.

turn property

turn: Color

The side to move.

__eq__

__eq__(other: object) -> bool

Boards are equal if their current positions are equal.

copy

copy() -> Board

An independent copy of the board, including the move history.

fen

fen() -> str

The current position in FEN notation.

is_game_over

is_game_over() -> bool

Whether the game is over.

is_legal(move: Move) -> bool

Whether move is legal in the current position.

outcome

outcome() -> Outcome | None

The outcome if the game is over, else None.

parse_move

parse_move(text: str) -> Move

Matches move text against the legal moves.

Accepts 32-28, 28x19, Hub notation listing the captured squares (28x19x23) and PDN capture paths (28x19x10).

Raises:

Type Description
IllegalMoveError

If no single legal move matches.

piece_at

piece_at(square: int) -> Piece | None

The piece on square (1 to 50), if any.

Raises:

Type Description
ValueError

If square is not between 1 and 50.

piece_map

piece_map() -> dict[int, Piece]

All pieces by square.

pop

pop() -> Move

Takes back the last move and returns it.

Raises:

Type Description
IndexError

If no move has been played.

push

push(move: Move | str) -> Move

Plays a move given as a Move or as text and returns it.

Raises:

Type Description
IllegalMoveError

If the move is illegal.

zobrist_hash

zobrist_hash() -> int

A 64-bit Zobrist hash of the current position.

dame.Move

A legal move: origin, destination and the captured squares.

Moves are obtained from Board.legal_moves, Board.parse_move or a search. str(move) gives standard notation (32-28, 28x19); move.hub() also lists the captured squares (28x19x23), which is unambiguous.

captured property

captured: list[int]

The squares of the captured pieces in ascending order.

from_square property

from_square: int

The origin square, 1 to 50.

is_capture property

is_capture: bool

Whether the move captures.

to_square property

to_square: int

The destination square, 1 to 50.

hub

hub() -> str

The move in Hub notation, which lists the captured squares.

dame.Piece

A piece: a color and whether it is a king.

color property

color: Color

The owner of the piece.

is_king property

is_king: bool

Whether the piece is a king.

symbol

symbol() -> str

w/b for men, W/B for kings.

dame.Color

Bases: Enum

A side. White moves first.

__invert__

__invert__() -> Color

The other side: ~Color.WHITE is Color.BLACK.

Game results

dame.Outcome

The result of a finished game.

termination property

termination: Termination

The rule that ended the game.

winner property

winner: Color | None

The winner, or None for a draw.

result

result() -> str

The PDN result: "2-0", "0-2" or "1-1".

dame.Termination

Bases: Enum

Why a game ended.

FIVE_MOVES class-attribute instance-attribute

FIVE_MOVES = 4

A lone king against at most two pieces including a king, for 5 moves each.

NO_MOVES class-attribute instance-attribute

NO_MOVES = 0

The side to move has no legal move and loses.

REPETITION class-attribute instance-attribute

REPETITION = 1

The same position occurred three times.

SIXTEEN_MOVES class-attribute instance-attribute

SIXTEEN_MOVES = 3

A lone king against three pieces including a king, for 16 moves each.

TWENTY_FIVE_MOVES class-attribute instance-attribute

TWENTY_FIVE_MOVES = 2

25 moves by each side with only kings moved and nothing captured.

Engine

dame.Engine

A search engine. Reusing one engine across moves keeps its hash table.

The search runs without holding the GIL, so other Python threads keep running; KeyboardInterrupt stops it.

Parameters:

Name Type Description Default
hash_mb int

Transposition table size in MiB.

64
book OpeningBook | None

An opening book to play from before searching.

None

Examples:

>>> engine = Engine(hash_mb=16)
>>> result = engine.search(Board("W:WK46:B10"), depth=4)
>>> result.best_move, result.mate
(Move('46x5x10'), 1)

clear

clear() -> None

Clears the hash table and move-ordering statistics, e.g. for a new game.

search

search(board: Board, *, depth: int | None = None, nodes: int | None = None, time: float | None = None, info: Callable[[SearchInfo], object] | None = None) -> SearchResult

Searches the current position of board.

The search stops at the first limit reached. Without limits it runs until stop() is called from another thread.

Parameters:

Name Type Description Default
board Board

The position to search, with its history for repetitions.

required
depth int | None

Maximum depth in plies.

None
nodes int | None

Maximum number of nodes.

None
time float | None

Maximum time in seconds.

None
info Callable[[SearchInfo], object] | None

Called with a SearchInfo after each completed iteration.

None

Returns:

Type Description
SearchResult

The best move with its score and principal variation.

Raises:

Type Description
ValueError

If a limit is invalid.

stop

stop() -> None

Asks a running search to stop; it returns its best move so far.

dame.SearchResult

The outcome of a search.

best_move property

best_move: Move | None

The best move, or None if the game is over.

depth property

depth: int

The last completed depth; 0 for book moves.

elapsed property

elapsed: float

Seconds spent.

from_book property

from_book: bool

Whether the move came from the opening book.

mate property

mate: int | None

Moves until mate for a forced win (positive) or loss (negative), else None.

nodes property

nodes: int

The number of nodes searched.

ponder property

ponder: Move | None

The expected reply.

pv property

pv: list[Move]

The principal variation.

score property

score: int

The score in centi-men from the side to move's point of view.

dame.SearchInfo

Progress reported after each completed search iteration.

depth property

depth: int

The completed depth in plies.

elapsed property

elapsed: float

Seconds spent so far.

nodes property

nodes: int

Nodes searched so far.

pv property

pv: list[Move]

The principal variation.

score property

score: int

The score in centi-men from the side to move's point of view.

seldepth property

seldepth: int

The deepest ply reached, including captures resolved at the leaves.

dame.OpeningBook

An opening book: weighted moves by position.

A book is built from games in PDN: the first moves of each game are added from the starting position, and moves shared by several games gain weight.

Examples:

>>> book = OpeningBook.from_pdn("1. 32-28 18-23 *\n1. 32-28 17-21 *\n1. 33-28 *")
>>> book.moves(Board())
[(Move('32-28'), 2), (Move('33-28'), 1)]

from_file staticmethod

from_file(path: str | PathLike[str], *, plies: int = 20) -> OpeningBook

Builds a book from the first plies moves of each game in the PDN file at path.

Raises:

Type Description
OSError

If the file cannot be read.

ValueError

If a game contains an illegal move.

from_pdn staticmethod

from_pdn(text: str, *, plies: int = 20) -> OpeningBook

Builds a book from the first plies moves of each game in PDN text.

Games of other variants (a GameType other than 20) and games that start from another position (a FEN tag) are skipped.

Raises:

Type Description
ValueError

If a game contains an illegal move.

moves

moves(board: Board) -> list[tuple[Move, int]]

The book moves for the current position with their weights, heaviest first.

Utilities

dame.perft builtin

perft(board: Board, depth: int) -> int

Counts the leaf nodes of the legal move tree at depth plies.

dame.IllegalMoveError

Bases: ValueError

Raised when a move is illegal or cannot be parsed.