Skip to main content
https://travis-ci.org/niklasf/python-chess.svg?branch=v0.11.0 https://coveralls.io/repos/niklasf/python-chess/badge.png https://landscape.io/github/niklasf/python-chess/master/landscape.png https://badge.fury.io/py/python-chess.svg https://readthedocs.org/projects/python-chess/badge/?version=v0.11.0

Introduction

python-chess is a pure Python chess library with move generation and validation and handling of common formats. This is the scholars mate in python-chess:

>>> import chess

>>> board = chess.Board()

>>> board.push_san("e4")
Move.from_uci('e2e4')
>>> board.push_san("e5")
Move.from_uci('e7e5')
>>> board.push_san("Qh5")
Move.from_uci('d1h5')
>>> board.push_san("Nc6")
Move.from_uci('b8c6')
>>> board.push_san("Bc4")
Move.from_uci('f1c4')
>>> board.push_san("Nf6")
Move.from_uci('g8f6')
>>> board.push_san("Qxf7")
Move.from_uci('h5f7')

>>> board.is_checkmate()
True

Documentation

https://python-chess.readthedocs.org/en/v0.11.0/

Features

  • Supports Python 2.7 and Python 3.3+.

    >>> # Python 2 compability for the following examples.
    >>> from __future__ import print_function
  • Supports standard chess and Chess960.

    >>> board = chess.Board(chess960=True)
  • Legal move generator and move validation. This includes all castling rules and en passant captures.

    >>> board = chess.Board()
    >>> board.legal_moves # doctest: +ELLIPSIS
    <LegalMoveGenerator at 0x... (Na3, Nc3, Nf3, Nh3, a3, b3, c3, d3, e3, f3, g3, h3, a4, b4, c4, d4, e4, f4, g4, h4)>
    >>> chess.Move.from_uci("a8a1") in board.legal_moves
    False
  • Make and unmake moves.

    >>> Nf3 = chess.Move.from_uci("g1f3")
    >>> board.push(Nf3) # Make the move
    
    >>> board.pop() # Unmake the last move
    Move.from_uci('g1f3')
  • Show a simple ASCII board.

    >>> board = chess.Board("r1bqkb1r/pppp1Qpp/2n2n2/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQkq - 0 4")
    >>> print(board)
    r . b q k b . r
    p p p p . Q p p
    . . n . . n . .
    . . . . p . . .
    . . B . P . . .
    . . . . . . . .
    P P P P . P P P
    R N B . K . N R
  • Detects checkmates, stalemates and draws by insufficient material.

    >>> board.is_stalemate()
    False
    >>> board.is_insufficient_material()
    False
    >>> board.is_game_over()
    True
    >>> board.halfmove_clock
    0
  • Detects repetitions. Has a half move clock.

    >>> board.can_claim_threefold_repetition()
    False
    >>> board.halfmove_clock
    0
    >>> board.can_claim_fifty_moves()
    False
    >>> board.can_claim_draw()
    False

    With the new rules from July 2014 a game ends drawn (even without a claim) once a fivefold repetition occurs or if there are 75 moves without a pawn push or capture. Other ways of ending a game take precedence.

    >>> board.is_fivefold_repetition()
    False
    >>> board.is_seventyfive_moves()
    False
  • Detects checks and attacks.

    >>> board.is_check()
    True
    >>> board.is_attacked_by(chess.WHITE, chess.E8)
    True
    
    >>> attackers = board.attackers(chess.WHITE, chess.F3)
    >>> attackers
    SquareSet(0b100000001000000)
    >>> chess.G2 in attackers
    True
    >>> print(attackers)
    . . . . . . . .
    . . . . . . . .
    . . . . . . . .
    . . . . . . . .
    . . . . . . . .
    . . . . . . . .
    . . . . . . 1 .
    . . . . . . 1 .
  • Detects absolute pins and their directions.

    >>> board.is_pinned(chess.BLACK, chess.E8)
    True
    >>> pin = board.pin(chess.BLACK, chess.E8)
    >>> pin
    SquareSet(0b1000000100000010000001000000000000000000000000000000000000000)
    >>> print(pin)
    . . . . 1 . . .
    . . . . . 1 . .
    . . . . . . 1 .
    . . . . . . . 1
    . . . . . . . .
    . . . . . . . .
    . . . . . . . .
    . . . . . . . .
  • Parses and creates SAN representation of moves.

    >>> board = chess.Board()
    >>> board.san(chess.Move(chess.E2, chess.E4))
    'e4'
  • Parses and creates FENs, extended FENs and Shredder FENs.

    >>> board.fen()
    'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
    >>> board.shredder_fen()
    'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w HAha - 0 1'
    >>> board = chess.Board("8/8/8/2k5/4K3/8/8/8 w - - 4 45")
    >>> board.piece_at(chess.C5)
    Piece.from_symbol('k')
  • Parses and creates EPDs.

    >>> board = chess.Board()
    >>> board.epd(bm=board.parse_uci("d2d4"))
    'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - bm d4;'
    
    >>> ops = board.set_epd("1k1r4/pp1b1R2/3q2pp/4p3/2B5/4Q3/PPP2B2/2K5 b - - bm Qd1+; id \"BK.01\";")
    >>> ops == {'bm': [chess.Move.from_uci('d6d1')], 'id': 'BK.01'}
    True
  • Read Polyglot opening books. Docs.

    >>> import chess.polyglot
    
    >>> book = chess.polyglot.open_reader("data/polyglot/performance.bin")
    
    >>> board = chess.Board()
    >>> main_entry = book.find(board)
    >>> main_entry.move()
    Move.from_uci('e2e4')
    >>> main_entry.weight
    1
    >>> main_entry.learn
    0
    
    >>> book.close()
  • Read and write PGNs. Supports headers, comments, NAGs and a tree of variations. Docs.

    >>> import chess.pgn
    
    >>> pgn = open("data/pgn/molinari-bordais-1979.pgn")
    >>> first_game = chess.pgn.read_game(pgn)
    >>> pgn.close()
    
    >>> first_game.headers["White"]
    'Molinari'
    >>> first_game.headers["Black"]
    'Bordais'
    
    >>> # Iterate through the mainline of this embarrasingly short game.
    >>> node = first_game
    >>> while node.variations:
    ...     next_node = node.variation(0)
    ...     print(node.board().san(next_node.move))
    ...     node = next_node
    e4
    c5
    c4
    Nc6
    Ne2
    Nf6
    Nbc3
    Nb4
    g3
    Nd3#
    
    >>> first_game.headers["Result"]
    '0-1'
  • Probe Syzygy endgame tablebases (DTZ, WDL). Docs.

    >>> import chess.syzygy
    
    >>> tablebases = chess.syzygy.open_tablebases("data/syzygy")
    
    >>> # Black to move is losing in 53 half moves (distance to zero) in this
    >>> # KNBvK endgame.
    >>> board = chess.Board("8/2K5/4B3/3N4/8/8/4k3/8 b - - 0 1")
    >>> tablebases.probe_dtz(board)
    -53
    
    >>> tablebases.close()
  • Probe Gaviota endgame tablebases (DTM, WDL) via a wrapper around libgtb. Docs.

    >>> import chess.gaviota
    
    >>> tablebases = chess.gaviota.open_tablebases("data/gaviota")
    
    >>> # White to move mates in 31 half moves in this KRvK endgame.
    >>> board = chess.Board("8/8/8/8/4k3/8/6R1/7K w - - 0 1")
    >>> tablebases.probe_dtm(board)
    31
    
    >>> tablebases.close()
  • Communicate with an UCI engine. Docs.

    >>> import chess.uci
    >>> import time
    
    >>> engine = chess.uci.popen_engine("stockfish")
    >>> engine.uci()
    >>> engine.author
    'Tord Romstad, Marco Costalba and Joona Kiiski'
    
    >>> # Synchronous mode.
    >>> board = chess.Board("1k1r4/pp1b1R2/3q2pp/4p3/2B5/4Q3/PPP2B2/2K5 b - - 0 1")
    >>> engine.position(board)
    >>> engine.go(movetime=2000) # Gets tuple of bestmove and ponder move.
    BestMove(bestmove=Move.from_uci('d6d1'), ponder=Move.from_uci('c1d1'))
    
    >>> # Asynchronous mode.
    >>> def callback(command):
    ...    bestmove, ponder = command.result()
    ...    assert bestmove == chess.Move.from_uci('d6d1')
    ...
    >>> command = engine.go(movetime=2000, async_callback=callback)
    >>> command.done()
    False
    >>> command.result()
    BestMove(bestmove=Move.from_uci('d6d1'), ponder=Move.from_uci('c1d1'))
    >>> command.done()
    True
    
    >>> # Quit.
    >>> engine.quit()
    0

Peformance

python-chess is not intended to be used by serious chess engines where performance is critical. The goal is rather to create a simple and relatively highlevel library.

You can install the gmpy2 or gmpy (https://pypi.python.org/pypi/gmpy2) modules in order to get a slight performance boost on basic operations like bitscans and population counts.

python-chess only imports very basic general (non-chess-related) operations from native libraries. All logic is pure Python. There will always be pure Python fallbacks.

Installing

  • With pip:

    pip install futures # Backport for Python < 3.2
    pip install python-chess
  • From current source code:

    python setup.py sdist
    python setup.py install

License

python-chess is licensed under the GPL3. See the LICENSE file for the full copyright and license information.

Thanks to Sam Tannous for publishing his approach to avoid rotated bitboards with direct lookup (pdf) alongside his GPL2+ engine Shatranj. Some of the bitboard move generation parts are ported from there.

Thanks to Ronald de Man for his Syzygy endgame tablebases (https://github.com/syzygy1/tb). The probing code in python-chess is very directly ported from his C probing code.

Thanks to Miguel A. Ballicora for his Gaviota tablebases (https://github.com/michiguel/Gaviota-Tablebases).

Release files for python-chess 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-chess 0.11.0
File Size Uploaded
python-chess-0.11.0.tar.gz 91.7 kB Details

Release files / python-chess-0.11.0.tar.gz

Download URL python-chess-0.11.0.tar.gz
Size 91.7 kB
Tags Source
SHA-256 checksum
How to use checksums
611de2c09046b2d4a6e537a607ad18b12433d584a7d2ff99441125ab2559f067
BLAKE2b-256 checksum
How to use checksums
47ca44e2f809c75d415b77288f360aee3ca87313d2cd762bedbbf20a0946ee51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

1.999

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.31.3

2 release files

0.31.0

2 release files

0.30.1

2 release files

0.28.2

2 release files

0.28.1

2 release files

0.28.0

2 release files

0.27.3

2 release files

0.27.2

2 release files

0.27.1

2 release files

0.27.0

2 release files

0.26.0

2 release files

0.25.1

2 release files

0.25.0

2 release files

0.24.1

1 release file

0.24.0

1 release file

0.23.10

1 release file

0.23.9

1 release file

0.23.8

1 release file

0.23.7

1 release file

0.23.6

1 release file

0.23.5

1 release file

0.23.4

1 release file

0.23.3

1 release file

0.23.2

1 release file

0.23.1

1 release file

0.23.0

1 release file

0.22.2

1 release file

0.22.1

1 release file

0.22.0

1 release file

0.21.2

1 release file

0.21.1

1 release file

0.21.0

1 release file

0.20.1

1 release file

0.20.0

1 release file

0.19.0

1 release file

0.18.4

1 release file

0.18.3

1 release file

0.18.2

1 release file

0.18.1

1 release file

0.18.0

1 release file

0.17.0

1 release file

0.16.2

1 release file

0.16.1

1 release file

0.16.0

1 release file

0.15.4

1 release file

0.15.3

1 release file

0.15.2

1 release file

0.15.1

1 release file

0.15.0

1 release file

0.14.1

1 release file

0.14.0

1 release file

0.13.3

1 release file

0.13.2

1 release file

0.13.1

1 release file

0.13.0

1 release file

0.12.5

1 release file

0.12.4

1 release file

0.12.3

1 release file

0.12.2

1 release file

0.12.1

1 release file

0.12.0

1 release file

0.11.1

1 release file

This release

0.11.0 This release

1 release file

0.10.1

1 release file

0.10.0

1 release file

0.9.1

1 release file

0.9.0

1 release file

0.8.3

1 release file

0.8.2

1 release file

0.8.1

1 release file

0.8.0

1 release file

0.7.0

1 release file

0.6.0

1 release file

0.5.0

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.2.0

1 release file

0.1.0

1 release file

0.0.6

2 release files

0.0.5

2 release files

0.0.4

1 release file

0.0.3

1 release file

0.0.2

1 release file

0.0.1

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page