Utilities#

class Color#

Represents either White or Black, used to identify the two players and their pieces.

static from_str(name: str) Color#

Return the color corresponding to name (case‑insensitive).

Parameters:

name (str) – The string "white" or "black" in any case.

Returns:

The matching Color instance.

Return type:

Color

Raises:

ValueError – If name is not recognized.

>>> Color.from_str("White") is WHITE
True
>>> Color.from_str("BLACK") is BLACK
True
property opposite: Color#

Gets the opposite Color to this one.

Returns:

The opposite Color instance.

Return type:

Color

>>> WHITE.opposite is BLACK
True
>>> BLACK.opposite is WHITE
True
WHITE: Color#

The white player

BLACK: Color#

The black player

class PieceType#

Represents one of the 6 types of pieces in chess, either a pawn, knight, bishop, rook, queen, or king.

static from_str(piece_type: str) PieceType#

Return the piece type corresponding to name (case‑insensitive).

Parameters:

name (str) – One of "pawn", "knight", "bishop", "rook", "queen" or "king" (any case).

Return type:

PieceType

Returns:

The matching PieceType.

Raises:

ValueError – If name is not recognized.

>>> PieceType.from_str("pawn") is PAWN
True
>>> PieceType.from_str("kNiGhT") is KNIGHT
True
PAWN: PieceType#

The PieceType for pawns

KNIGHT: PieceType#

The PieceType for knights

BISHOP: PieceType#

The PieceType for bishops

ROOK: PieceType#

The PieceType for rooks

QUEEN: PieceType#

The PieceType for queens

KING: PieceType#

The PieceType for kings

PIECE_TYPES: list[PieceType]#

A list of all PieceType values. In the order of [PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING]

class Piece(color: Color, type: PieceType)#

Represents a piece with both a Color and a PieceType, such as a White Pawn, or a Black Rook.

static from_chr(char: str) Piece#

Return the piece encoded by char (ASCII piece letter).

Uppercase letters encode WHITE pieces, lowercase letters encode BLACK.

Parameters:

char (str) – One of PRNBQKprnbqk.

Return type:

Piece

Returns:

The corresponding Piece.

Raises:

ValueError – If char is not a valid piece letter.

>>> Piece.from_chr("P")
<Piece: (White, Pawn)>
>>> Piece.from_chr("n")
<Piece: (Black, Knight)>
property piece_type: PieceType#

Gets the PieceType of this Piece.

property color: Color#

Gets the Color of this Piece.

unicode() str#

Returns Unicode figurine character corresponding to this Piece.

>>> Piece(WHITE, PAWN).unicode()
"♙"
>>> Piece(BLACK, KNIGHT).unicode()
"♞"
class Square#

Represents one of the 64 squares on a chess board.

static from_str(name: str) Square#

Return the Square encoded by name (case‑insensitive).

Parameters:

name (str) – The name of the square

Return type:

Square

Returns:

The corresponding Square

Raises:

ValueError if given a string which does not represent a Square

>>> Square.from_string("E1") == E1
True
>>> Square.from_string("a2") == A2
Tru
bb() Bitboard#

Creates a Bitboard containing only this Square.

>>> A1.bb() == Bitboard([A1])
True
>>> H3.bb() == Bitboard([H3])
True
index() int#

Returns the index of this Square in the provided SQUARES list.

>>> A1.index()
0
>>> B1.index()
1
>>> A2.index()
8
>>> H8.index()
63
adjacent() Bitboard#

Creates a Bitboard of all neighbors orthogonal or diagonal to this Square.

>>> A1.adjacent() == Bitboard([A2, B1, B2])
True
>>> E5.adjacent() == Bitboard([D4, D5, D6, E4, E6, F4, F5, F6])
True
north(distance: int = 1) Square | None#

Return the square that is the given distance number of ranks above this square.

Parameters:

distance – how many ranks to move north.

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> B6.north() is B7
True
>>> A1.north(distance=3) is A4
True
>>> B8.north(distance=2)
None
south(distance: int = 1) Square | None#

Return the square that is the given distance number of ranks below this square.

Parameters:

distance (int, default = 1) – how many ranks to move south.

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> B6.south() is B5
True
>>> B8.south(distance=2) is B6
True
>>> A1.south(distance=3)
None
east(distance: int = 1) Square | None#

Return the square that is the given distance number of files to the east of this square.

Parameters:

distance (int, default = 1) – how many files to move east (toward the H-file).

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> B6.east() is C6
True
>>> A1.east(distance=3) is D1
True
>>> H8.east(distance=2)
None
west(distance: int = 1) Square | None#

Return the square that is the given distance number of files to the west of this square.

Parameters:

distance (int, default = 1) – how many files to move west (toward the A-file).

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> B6.west() == A6
True
>>> H8.west(distance=2) == E8
True
>>> A1.west(distance=3)
None
nw(distance: int = 1) Square | None#

Return the square that is the given distance number of files west and ranks north of this square.

Parameters:

distance (int, default = 1) – number of steps to move north-west.

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> C3.nw() == B4
True
>>> A1.nw()
None
>>> D4.nw(distance=2) == B6
True
ne(distance: int = 1) Square | None#

Return the square that is the given distance number of files east and ranks north of this square.

Parameters:

distance (int, default = 1) – number of steps to move north-east.

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> C3.ne() is D4
True
>>> E4.ne(distance = 2) is G2
True
>>> H8.ne()
None
sw(distance: int = 1) Square | None#

Return the square that is the given distance number of files west and ranks south of this square.

Parameters:

distance (int, default = 1) – number of steps to move south-west.

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> C3.sw() is B2
True
>>> E4.sw(distance = 2) is C6
True
>>> A1.sw()
None
se(distance: int = 1) Square | None#

Return the square that is the given distance number of files east and ranks south of this square.

Parameters:

distance (int, default = 1) – number of steps to move south-east.

Returns:

the target square, or None if it would be off the board.

Return type:

Square | None

>>> C3.se() is D2
True
>>> E4.se(distance = 2) is G6
True
>>> H1.se()
None
A1: Square#

The A1 Square

B1: Square#

The B1 Square

C1: Square#

The C1 Square

D1: Square#

The D1 Square

E1: Square#

The E1 Square

F1: Square#

The F1 Square

G1: Square#

The G1 Square

H1: Square#

The H1 Square

A2: Square#

The A2 Square

B2: Square#

The B2 Square

C2: Square#

The C2 Square

D2: Square#

The D2 Square

E2: Square#

The E2 Square

F2: Square#

The F2 Square

G2: Square#

The G2 Square

H2: Square#

The H2 Square

A3: Square#

The A3 Square

B3: Square#

The B3 Square

C3: Square#

The C3 Square

D3: Square#

The D3 Square

E3: Square#

The E3 Square

F3: Square#

The F3 Square

G3: Square#

The G3 Square

H3: Square#

The H3 Square

A4: Square#

The A4 Square

B4: Square#

The B4 Square

C4: Square#

The C4 Square

D4: Square#

The D4 Square

E4: Square#

The E4 Square

F4: Square#

The F4 Square

G4: Square#

The G4 Square

H4: Square#

The H4 Square

A5: Square#

The A5 Square

B5: Square#

The B5 Square

C5: Square#

The C5 Square

D5: Square#

The D5 Square

E5: Square#

The E5 Square

F5: Square#

The F5 Square

G5: Square#

The G5 Square

H5: Square#

The H5 Square

A6: Square#

The A6 Square

B6: Square#

The B6 Square

C6: Square#

The C6 Square

D6: Square#

The D6 Square

E6: Square#

The E6 Square

F6: Square#

The F6 Square

G6: Square#

The G6 Square

H6: Square#

The H6 Square

A7: Square#

The A7 Square

B7: Square#

The B7 Square

C7: Square#

The C7 Square

D7: Square#

The D7 Square

E7: Square#

The E7 Square

F7: Square#

The F7 Square

G7: Square#

The G7 Square

H7: Square#

The H7 Square

A8: Square#

The A8 Square

B8: Square#

The B8 Square

C8: Square#

The C8 Square

D8: Square#

The D8 Square

E8: Square#

The E8 Square

F8: Square#

The F8 Square

G8: Square#

The G8 Square

H8: Square#

The H8 Square

SQUARES: list[Square]#

Every defined Square, in the order of [A1, B1, C1, D1, E1, F1, G1, H1, A2, B2, ..., H8].

SQUARES_FLIPPED: list[Square]#

Every defined Square, but flipped to be in the order of [A8, B8, C8, D8, E8, F8, G8, H8, A7, B7, ..., H1].

class Bitboard(squares: Collection[Square])#

A set of squares represented as a 64-bit integer, where each bit indicates whether a Square is included.

static from_int(value: int) Bitboard#

Construct a Bitboard from its integer encoding (see __int__()).

Parameters:

value (int) – 64-bit integer to convert.

Returns:

new Bitboard corresponding to value.

Return type:

Bitboard

Raises:

OverflowError – if value < 0 or value >= 2 ** 64

>>> Bitboard.from_int(0) == Bitboard([])
True
>>> Bitboard.from_int(1) == Bitboard([A1])
True
>>> Bitboard.from_int(269498368) == Bitboard([E2, E3, E4, D2, F2])
True
>>> Bitboard.from_int(0xFFFF_FFFF_FFFF_FFFF) == FULL_BB
True
RANK_1: Bitboard#

Bitboard containing every square on Rank 1

RANK_2: Bitboard#

Bitboard containing every square on Rank 2

RANK_3: Bitboard#

Bitboard containing every square on Rank 3

RANK_4: Bitboard#

Bitboard containing every square on Rank 4

RANK_5: Bitboard#

Bitboard containing every square on Rank 5

RANK_6: Bitboard#

Bitboard containing every square on Rank 6

RANK_7: Bitboard#

Bitboard containing every square on Rank 7

RANK_8: Bitboard#

Bitboard containing every square on Rank 8

RANKS: list[Bitboard]#

List of the eight rank Bitboard values in order, from RANK_1 to RANK_8.

A_FILE: Bitboard#

Bitboard containing every square on the A-file.

B_FILE: Bitboard#

Bitboard containing every square on the B-file.

C_FILE: Bitboard#

Bitboard containing every square on the C-file.

D_FILE: Bitboard#

Bitboard containing every square on the D-file.

E_FILE: Bitboard#

Bitboard containing every square on the E-file.

F_FILE: Bitboard#

Bitboard containing every square on the F-file

G_FILE: Bitboard#

Bitboard containing every square on the G-file.

H_FILE: Bitboard#

Bitboard containing every square on the H-file.

FILES: list[Bitboard]#

List of the eight file Bitboard values in order, from A_FILE to H_FILE.

FULL_BB: Bitboard#

Bitboard containing all 64 squares

EMPTY_BB: Bitboard#

Bitboard containing no squares

LIGHT_SQUARE_BB: Bitboard#

Bitboard of all light colored squares (B1, D1, etc.)

DARK_SQUARE_BB: Bitboard#

Bitboard of all dark colored squares (A1, C1, etc.)

class CastlingType#

One of four legal castling options: the king moves either kingside or queenside for WHITE or BLACK.

static from_chr(castling_type: str) CastlingType#

Return the castling type corresponding to a single-character code.

Parameters:

castling_type (str) – one of "K", "Q", "k", "q".

Returns:

the matching CastlingType.

Return type:

CastlingType

Raises:

ValueError – if castling_type is not a valid code.

>>> CastlingType.from_chr("K") is WHITE_KINGSIDE
True
>>> CastlingType.from_chr("Q") is WHITE_QUEENSIDE
True
>>> CastlingType.from_chr("k") is BLACK_KINGSIDE
True
>>> CastlingType.from_chr("q") is BLACK_QUEENSIDE
True
WHITE_KINGSIDE: CastlingType#

Castling type representing WHITE kingside castling.

WHITE_QUEENSIDE: CastlingType#

Castling type representing WHITE queenside castling.

BLACK_KINGSIDE: CastlingType#

Castling type representing BLACK kingside castling.

BLACK_QUEENSIDE: CastlingType#

Castling type representing BLACK queenside castling.

class Move(origin: Square, destination: Square, promote_to: PieceType | None = None)#

A chess move, defined by its origin and destination squares and an optional promotion piece type.

static castle(castling_type: CastlingType) Move#

Return the move corresponding to castling_type.

Parameters:

castling_type (CastlingType) – one of the four castling constants.

Returns:

appropriate king move for that castling.

Return type:

Move

>>> Move.castle(WHITE_KINGSIDE) == Move(E1, G1)
True
>>> Move.castle(WHITE_QUEENSIDE) == Move(E1, C1)
True
>>> Move.castle(BLACK_KINGSIDE) == Move(E8, G8)
True
>>> Move.castle(BLACK_QUEENSIDE) == Move(E8, C8)
True
static from_uci(uci: str) Move | None#

Parse a UCI long-algebraic str and build a move.

Null moves are supported as “0000”, and are represented as None.

Parameters:

uci (str) – UCI string such as "e2e4" or "b7b8q".

Returns:

move instance, or None for a null move.

Return type:

Move | None

Raises:

ValueError – if uci is malformed or illegal.

>>> Move.from_uci("e2e4") == Move(E2, E4)
True
>>> Move.from_uci("a1d4") == Move(A1, D4)
True
>>> Move.from_uci("b7b8q") == Move(B7, B8, promote_to=QUEEN)
True
>>> Move.from_uci("0000") is None
True
static from_san(san: str, board: Board) Move#

Parse a SAN str in the context of board.

Parameters:
  • san (str) – SAN text (e.g. "Nf6", "O-O", "e4").

  • board (Board) – position used to disambiguate the SAN.

Returns:

the corresponding move.

Return type:

Move

Raises:

ValueError – if san is invalid for board.

>>> Move.from_san("e4", Board()) == Move(E2, E4)
True
>>> FEN = "r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3"
>>> board = Board.from_fen(FEN)
>>> Move.from_san("Nf6", board) == Move(G8, F6)
True
san(board: Board) str#

Return this move in SAN notation relative to board.

Parameters:

board (Board) – position that provides context.

Returns:

SAN string.

Return type:

str

Raises:

ValueError – if the move is illegal for board.

>>> Move(E2, E4).san(Board())
'e4'
>>> FEN = "r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4"
>>> Move(E1, G1).san(Board.from_fen(FEN))
'O-O'
uci() str#

Return a str of the UCI long algebraic notation representation of this move.

Returns:

UCI string.

Return type:

str

>>> Move(E2, E4).uci()
'e2e4'
>>> Move(A1, D4).uci()
'a1d4'
>>> Move(B7, B8, promote_to=QUEEN).uci()
'b7b8q'
property origin: Square#

The Square the piece moves from.

>>> Move(E2, E4).origin is E2
True
>>> Move.from_uci("a1d4").origin is A1
True
property destination: Square#

The Square the piece moves to.

>>> Move(E2, E4).destination is E4
True
>>> Move.from_uci("a1d4").destination is D4
True
property promotion: PieceType | None#

Promotion PieceType, or None for a non-promotion.

>>> Move.from_uci("b7b8q").promotion is QUEEN
True
>>> Move(E2, E4).promotion is None
True
is_promotion() bool#

Return True if the move is a promotion.

>>> Move.from_uci("b7b8q").is_promotion()
True
>>> Move(E2, E4).is_promotion()
False
is_capture(board: Board) bool#

Return True if the move captures a piece on board.

Parameters:

board (Board) – position to check if this is a capture.

Returns:

capture flag.

Return type:

bool

>>> FEN = "r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3"
>>> board = Board.from_fen(FEN)
>>> Move(F3, E5).is_capture(board)
True
is_castling(board: Board) bool#

Return True if the move is a legal castling move on board.

Parameters:

board (Board) – position to check if this is a castling move.

Returns:

castling flag.

Return type:

bool

>>> FEN = "r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4"
>>> board = Board.from_fen(FEN)
>>> Move(E1, G1).is_castling(board)
True
>>> Move(E1, G1).is_castling(Board.empty())
False
castling_type(board: Board) CastlingType | None#

If the move is castling, return its type; otherwise None.

Parameters:

board (Board) – position used for classification.

Returns:

corresponding castling type or None.

Return type:

CastlingType | None

>>> FEN = "r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4"
>>> board = Board.from_fen(FEN)
>>> Move(E1, G1).castling_type(board) is WHITE_KINGSIDE
True
>>> Move(E1, G1).castling_type(Board.empty()) is None
True
class CastlingRights(castling_types: Collection[CastlingType])#

A set of CastlingType values that encodes a Board’s castling permissions.

static from_fen(castling_fen: str) CastlingRights#

Build a CastlingRights object from a FEN castling field.

Parameters:

castling_fen (str) – "KQkq", "KQ", "-"

Returns:

rights object matching castling_fen.

Return type:

CastlingRights

Raises:

ValueError – if castling_fen is not valid FEN.

>>> CastlingRights.from_fen("KQkq") == ALL_CASTLING
True
>>> CastlingRights.from_fen("Qk") == CastlingRights([WHITE_QUEENSIDE, BLACK_KINGSIDE])
True
>>> CastlingRights.from_fen("-") == NO_CASTLING
True
fen() str#

Returns the Forsyth-Edwards Notation str represetnation of this CastlingRights.

Returns:

"KQkq", "-" or similar.

Return type:

str

>>> NO_CASTLING.fen()
'-'
>>> CastlingRights([WHITE_KINGSIDE, WHITE_QUEENSIDE]).fen()
'KQ'
>>> ALL_CASTLING.fen()
'KQkq'
full(color: Color | None = None) bool#

Return True if all relevant rights are present.

Parameters:

color (Color | None) – optionally restrict the check to WHITE or BLACK.

Returns:

completeness flag.

Return type:

bool

>>> ALL_CASTLING.full()
True
>>> CastlingRights.from_fen("KQk").full()
False
>>> CastlingRights.from_fen("KQk").full(WHITE)
True
>>> NO_CASTLING.full()
False
any(color: Color | None = None) bool#

Return True if any castling right is present.

Parameters:

color (Color | None) – optionally restrict the check to WHITE or BLACK.

Returns:

presence flag.

Return type:

bool

>>> ALL_CASTLING.any()
True
>>> CastlingRights.from_fen("KQk").any()
True
>>> CastlingRights.from_fen("K").any()
True
>>> CastlingRights.from_fen("K").any(BLACK)
False
>>> NO_CASTLING.any()
False
kingside(color: Color | None = None) bool#

Return True if any kingside right is present.

Parameters:

color (Color | None) – optionally restrict the check to WHITE or BLACK.

Returns:

kingside flag.

Return type:

bool

>>> ALL_CASTLING.kingside()
True
>>> CastlingRights.from_fen("Q").kingside()
False
>>> CastlingRights.from_fen("K").kingside()
True
>>> CastlingRights.from_fen("K").kingside(BLACK)
False
>>> NO_CASTLING.kingside()
False
queenside(color: Color | None = None) bool#

Return True if any queenside right is present.

Parameters:

color (Color | None) – optionally restrict the check to WHITE or BLACK.

Returns:

queenside flag.

Return type:

bool

>>> ALL_CASTLING.queenside()
True
>>> CastlingRights.from_fen("Q").queenside()
True
>>> CastlingRights.from_fen("K").queenside()
False
>>> CastlingRights.from_fen("Q").queenside(BLACK)
False
>>> NO_CASTLING.queenside()
False
ALL_CASTLING: CastlingRights#

Castling rights which include all types of castling

NO_CASTLING: CastlingRights#

Castling rights which include no types of castling

class Board#

A mutable chess position.

A Board represents a configuration of chess pieces as a mapping of each Square to optional an Piece. The Board class includes attributes for CastlingRights, the existence of an en-passant Square, and the Color for the turn of the current player. Also holds the half-move clock and full-move number each as an int.

The Board class provides an interface for generating Move objects representing legal actions for a turn, as well as applying and undoing these moves.

static from_fen(fen: str) Board#

Build a board from a str of a Forsyth-Edwards Notation (FEN) representation of a position.

The FEN is not required to include a halfmove clock or fullmove number. The default values for these are 0 and 1.

Parameters:

fen (str) – full FEN record.

Returns:

board represented by fen.

Return type:

Board

Raises:

ValueError – if fen is malformed.

>>> board = Board.from_fen("rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2")
>>> print(board)
r n b q k b n r 
p p - p p p p p 
- - - - - - - - 
- - p - - - - - 
- - - - P - - - 
- - - - - N - - 
P P P P - P P P 
R N B Q K B - R 
static empty() Board#

Creates a completely empty Board, with no pieces on it.

Returns:

An empty position

Return type:

:class:Board

property turn: Color#

Side to move, either WHITE or BLACK.

property halfmove_clock: int#

Gets the current halfmove clock as an int. This represents the number of ply that have passed since a capture or pawn advance.

property fullmove_number: int#

Gets the current fullmove number as an int. This represents the total number of turns each player has taken since the start of a game.

property en_passant_square: Square | None#

Gets the current en passant Square, if it exists. Otherwise returns None.

property castling_rights: CastlingRights#

Gets the current CastlingRights of this Board.

legal_moves() list[Move]#

Generates a list of legal Move objects for this Board’s position.

Returns:

A list of legal moves for this position.

Return type:

list[Move]

>>> Board().legal_moves()
[<Move: b1a3>, <Move: b1c3>, <Move: g1f3>, <Move: g1h3>, <Move: a2a3>, <Move: a2a4>, <Move: b2b3>, <Move: b2b4>, <Move: c2c3>, <Move: c2c4>, <Move: d2d3>, <Move: d2d4>, <Move: e2e3>, <Move: e2e4>, <Move: f2f3>, <Move: f2f4>, <Move: g2g3>, <Move: g2g4>, <Move: h2h3>, <Move: h2h4>]
apply(move: Move | None) None#

Applies the given Move to this Board.

The Move argument is not checked to be legal outside of checking if the origin has a Piece. None can be passed as the argument to skip a turn.

Parameters:

move (Move | None) – The move to apply, or None for a null move.

Raises:

ValueError – if the origin of move does not have a piece.

>>> board = Board()
>>> board.apply(Move(E2, E4))
>>> print(board)
r n b q k b n r 
p p p p p p p p 
- - - - - - - - 
- - - - - - - - 
- - - - P - - - 
- - - - - - - - 
P P P P - P P P 
R N B Q K B N R 
Raises:

ValueError if the given Move’s origin is an empty square.

undo() Move | None#

Undoes the last Move applied to this Board.

Returns:

The last move applied to this board.

Return type:

Move | None

Raises:

AttributeError if there are no moves to undo. This is true when Board.history has a len() of 0

>>> board = Board()
>>> board.apply(Move(E2, E4))
>>> board.apply(Move(E7, E5))
>>> board.undo() == Move(E7, E5)
True
>>> print(board)
r n b q k b n r 
p p p p p p p p 
- - - - - - - - 
- - - - - - - - 
- - - - P - - - 
- - - - - - - - 
P P P P - P P P 
R N B Q K B N R 
Raises:

AttributeError if there are no moves to undo.

fen() str#

Gets the Forsyth-Edwards Notation representation as a str of this Board.

Returns:

A FEN representing the position

Return type:

str

>>> board = Board()
>>> board.fen()
'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
copy() Board#

Returns a new Board which is an exact copy of this Board, including its Move history.

Returns:

A deep copy of this position and its state.

Return type:

Board

property history: list[Move]#

Gets a list of Move objects of every Move which have been used with Board.apply() and have not been undone with Board.undo() for this Board

>>> board = Board()
>>> board.apply(Move(E2, E4))
>>> board.apply(Move(E7, E5))
>>> board.apply(Move(G1, F3))
>>> board.history
[<Move: e2e4>, <Move: e7e5>, <Move: g1f3>]
pretty(color_scheme: Board = Board.OAK, highlighted_squares: Bitboard = EMPTY_BB, targeted_squares: Bitboard = EMPTY_BB) str#

A pretty to-string method for terminal outputs.

Creates a str representation of this Board using Unicode chess figurines and the provided Board.ColorScheme as a palette for the background and highlights. Bitboard’s can be specified for highlighting particular squares, as for example a Move’s origin, as well as for targetting certain squares, as for possible Move destinations.

Returns:

A rendering of this position as a UTF-8 string with ANSI color codes

Return type:

str

class ColorScheme#

A pallete of colors to be used with Board.pretty() to stylize printed boards.

LAGOON: Board.ColorScheme#

A light blue color pallete

SLATE: Board.ColorScheme#

A slightly purplish, grey color pallete

OAK: Board.ColorScheme#

A classical, wood styled color pallete

WALNUT: Board.ColorScheme#

A less saturated wood styled color pallete

GREEN: Board.ColorScheme#

A familiar green and white color pallete

ROSE: Board.ColorScheme#

A pinkish red color pallete

CLAY: Board.ColorScheme#

A dulled, rosy brown and grey color pallete

STEEL: Board.ColorScheme#

A monochromatic grey color pallete

class BoardStatus#

A predicate-like object that answers the question “is this board in status X?” Examples of statuses include check, check-mate, stalemate, and repetition or 50-move draw claims.

CHECK: BoardStatus#

The side to move is in check

MATE: BoardStatus#

The side to move has no legal moves.

CHECKMATE: BoardStatus#

The side to move is in checkmate. The player is in check and has no legal moves.

STALEMATE: BoardStatus#

The side to move is in stalemate. The player has no legal moves but is not in check.

INSUFFICIENT_MATERIAL: BoardStatus#

There is not enough material for either player to be placed in checkmate.

FIFTY_MOVE_TIMEOUT: BoardStatus#

Fifty full-moves have passed without a pawn move or capture.

SEVENTY_FIVE_MOVE_TIMEOUT: BoardStatus#

Seventy five full-moves have passed without a pawn move or capture.

THREEFOLD_REPETITION: BoardStatus#

The same position has occured at least three times.

FIVEFOLD_REPETITION: BoardStatus#

The same position has occured at least five times.

DRAW: BoardStatus#

Any position in which a player may claim a draw. This includes stalemate, insufficient material, a fifty move timeout, or threefold repetition.

FORCED_DRAW: BoardStatus#

A forced draw. This includes stalemate, insufficient material, a seventy five move timeout, or fivefold repetition.

count_moves(board: bulletchess.Board) int#

Counts the number of legal moves that could be performed for the given Board, without actually constructing any Move objects. This is much faster than calling len(Board.legal_moves())

evaluate(board: bulletchess.Board) int#

A simple heuristic function for the utility of a Board based on Claude Shannon’s example evaluation function. This implementation differs in using centipawns instead of fractional values, and explicitly evaluates positions which can be claimed as a draw as 0. The number of Kings is reconsidered as whether or not a player is in Checkmate.

f(P) = 200(K-K’) + 9(Q-Q’) + 5(R-R’) + 3(B-B’+N-N’) + (P-P’) - 0.5(D-D’+S-S’+I-I’) + 0.1(M-M’)

in which:

1) K,Q,R,B,B,P are the number of White kings, queens, rooks, bishops, knights and pawns on the board.

2) D,S,I are doubled, backward and isolated White pawns.

3) M= White mobility (measured, say, as the number of legal moves available to White).

Primed letters are the similar quantities for Black.

Shannon, C. E. (1950). XXII. Programming a computer for playing chess. The London, Edinburgh, and Dublin Philosophical Magazine and Journal of Science, 41(314), 256–27 5. https://doi.org/10.1080/14786445008521796

is_quiescent(board: bulletchess.Board) bool#

Determines if the given Board’s position is ‘quiescent’, meaning that the position is not check, and that there are no possible captures that could be made on this turn.

>>> is_quiescent(Board())
True
>>> board = Board.from_fen("rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2")
>>> print(board)
r n b q k b n r 
p p p p - p p p 
- - - - - - - - 
- - - - p - - - 
- - - - P - - - 
- - - - - N - - 
P P P P - P P P 
R N B Q K B - R 
>>> is_quiescent(board)
True
>>> board = Board.from_fen("r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3")
>>> print(board)
r - b q k b n r 
p p p p - p p p 
- - n - - - - - 
- - - - p - - - 
- - - - P - - - 
- - - - - N - - 
P P P P - P P P 
R N B Q K B - R 
>>> is_quiescent(board)
False
perft(board: bulletchess.Board, depth: int) int#

Performs a tree walk of legal moves starting from the provided Board, and returns the number of leaf nodes at the given depth. For more information, see: https://www.chessprogramming.org/Perft

perft_fen(fen: str, depth: int) int#

Sames as utils.perft(), but takes a Forsyth-Edwards Notation str description of a position instead of a Board.

backwards_pawns(board: bulletchess.Board, color: bulletchess.Optional[bulletchess.Color] = None) bulletchess.Bitboard#

Returns a Bitboard containing all Square values with a backwards pawn for the given Board.

A backwards pawn is defined as a pawn that: - is behind all other friendly pawns in its own and adjacent files. - has no enemy pawn directly in front of it - can not advance without being attacked by an enemy pawn

>>> board = Board.from_fen("4k3/2p3p1/1p2p2p/1P2P2P/1PP3P1/4P3/8/4K3 w - - 0 1")
>>> print(board)
- - - - k - - - 
- - p - - - p - 
- p - - p - - p 
- P - - P - - P 
- P P - - - P - 
- - - - P - - - 
- - - - - - - - 
- - - - K - - - 
>>> print(backwards_pawns(board))
0 0 0 0 0 0 0 0 
0 0 1 0 0 0 1 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
isolated_pawns(board: bulletchess.Board, color: bulletchess.Optional[bulletchess.Color] = None) bulletchess.Bitboard#

Returns a Bitboard containing all Square values with an isolated pawn for the given Board.

An isolated pawn is defined as a pawn with no friendly pawns in adjacent files.

>>> board = Board.from_fen("4k3/2p3p1/1p2p2p/1P2P2P/1PP3P1/4P3/8/4K3 w - - 0 1")
>>> print(board)
- - - - k - - - 
- - p - - - p - 
- p - - p - - p 
- P - - P - - P 
- P P - - - P - 
- - - - P - - - 
- - - - - - - - 
- - - - K - - - 
>>> print(isolated_pawns(board))
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
doubled_pawns(board: bulletchess.Board, color: bulletchess.Optional[bulletchess.Color] = None) bulletchess.Bitboard#

Returns a Bitboard containing all Square values with a passed pawn for the given Board.

A doubled pawn is defined as a pawn with a friendly pawn in the same file.

>>> board = Board.from_fen("4k3/2p3p1/1p2p2p/1P2P2P/1PP3P1/4P3/8/4K3 w - - 0 1")
>>> print(board)
- - - - k - - - 
- - p - - - p - 
- p - - p - - p 
- P - - P - - P 
- P P - - - P - 
- - - - P - - - 
- - - - - - - - 
- - - - K - - - 
>>> print(doubled_pawns(board))
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 1 0 0 1 0 0 0 
0 1 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
passed_pawns(board: bulletchess.Board, color: bulletchess.Optional[bulletchess.Color] = None) bulletchess.Bitboard#

Returns a Bitboard containing all Square values with a passed pawn for the given Board.

A passed pawn is defined as a pawn with no enemy pawns in its file or adjacent files which can block it from advancing forward, ulitmately to promote.

>>> board = Board.from_fen("7k/8/7p/1P2Pp1P/2Pp1PP1/8/8/7K w - - 0 1")
>>> print(board)
- - - - - - - k 
- - - - - - - - 
- - - - - - - p 
- P - - P p - P 
- - P p - P P - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - K 
>>> print(passed_pawns(board))
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 1 0 0 1 0 0 0 
0 0 1 1 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
is_pinned(board: bulletchess.Board, square: bulletchess.Square) bool#

Returns True if the given Square has a piece which is pinned in the given Board.

A piece is considered pinned if it is not allowed to move at all, as doing so would place the moving player’s king in check.

>>> board = Board.from_fen("rnbqk1nr/pppp1ppp/8/4p3/1b6/2NP4/PPP1PPPP/R1BQKBNR w KQkq - 1 3")
>>> print(board)
r n b q k - n r 
p p p p - p p p 
- - - - - - - - 
- - - - p - - - 
- b - - - - - - 
- - N P - - - - 
P P P - P P P P 
R - B Q K B N R 
>>> is_pinned(board, A1)
False
>>> is_pinned(board, D3)
False
>>> is_pinned(board, C3)
True
attack_mask(board: bulletchess.Board, attacker: bulletchess.Color) bulletchess.Bitboard#

Returns a Bitboard of containing all squares which are being attacked by the specified Color.

>>> board = Board()
>>> print(attack_mask(board, WHITE))
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 
0 1 1 1 1 1 1 0 
>>> board = Board.from_fen("7k/8/8/1r6/8/8/8/7K w - - 0 1")
>>> print(board)
- - - - - - - k 
- - - - - - - - 
- - - - - - - - 
- r - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - K 
>>> print(attack_mask(board, BLACK))
0 1 0 0 0 0 1 0 
0 1 0 0 0 0 1 1 
0 1 0 0 0 0 0 0 
1 0 1 1 1 1 1 1 
0 1 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 
material(board: bulletchess.Board, pawn_value: int = 100, knight_value: int = 300, bishop_value: int = 300, rook_value: int = 500, queen_value: int = 900) int#

Calculates the net material value on the provided Board. By default, uses standard evaluations of each PieceType measured in centipawns.

mobility(board: bulletchess.Board) int#

Returns the number of moves for the Board as if it were it the WHITE’s turn, subtracted by the number of moves as if it were BLACK’s turn.

open_files(board: bulletchess.Board) bulletchess.Bitboard#

Returns a Bitboard of all files that have no pawns of either Color.

>>> board = Board.from_fen("4k3/2p3p1/1p2p2p/1P2P2P/1PP3P1/4P3/8/4K3 w - - 0 1")
>>> print(board)
- - - - k - - - 
- - p - - - p - 
- p - - p - - p 
- P - - P - - P 
- P P - - - P - 
- - - - P - - - 
- - - - - - - - 
- - - - K - - - 
>>> print(open_files(board))
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
1 0 0 1 0 1 0 0 
half_open_files(board: bulletchess.Board, for_color: bulletchess.Color) bulletchess.Bitboard#

Returns a Bitboard of all files that have no pawns of the given Color, but do have pawns of the opposite Color.

>>> board = Board.from_fen("3k4/8/4p3/4P3/5PP1/8/8/3K4 w - - 0 1")
>>> print(board)
- - - k - - - - 
- - - - - - - - 
- - - - p - - - 
- - - - P - - - 
- - - - - P P - 
- - - - - - - - 
- - - - - - - - 
- - - K - - - - 
>>> print(half_open_files(board, WHITE))
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
>>> print(half_open_files(board, BLACK))
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 
0 0 0 0 0 1 1 0 

Returns a random legal Move for the given Board.

This is much faster than random.choice(board.legal_moves()).

>>> board = Board()
>>> random_legal_move(board)
<Move: g1h3>
>>> random_legal_move(board)
<Move: d2d3>
random_board() bulletchess.Board#

Returns a Board with a position determined by applying a random number of randomly selected legal moves. The generated Board may be checkmate or a draw.

>>> board = random_board()
>>> print(board)
r Q - - k - - r 
- b - p n p p - 
p b - - p - - - 
- - - - - - P - 
- p P - - - p - 
N - - - - N - - 
P - - P P P - - 
R - B - K - - - 
>>> board2 = random_board()
>>> print(board2)
- - K - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- k - - - - - - 
- - - - - - - - 
legally_equal(board1: bulletchess.Board, board2: bulletchess.Board) bool#

Returns True if given two Board instances with the same mapping of Square to Piece objects, equivalent CastlingRights, and en-passant Square values.

Unlike Board.__eq__(), does not check the halfmove clock and fullmove number.

>>> board = Board()
>>> board2 = Board()
>>> board.halfmove_clock = 10
>>> board == board2
False
>>> legally_equal(board, board2)
True
deeply_equal(board1: bulletchess.Board, board2: bulletchess.Board) bool#

Returns True if given two Board instances have the same move history, along with equivalent mappings of Square to Piece objects, equivalent CastlingRights, and en-passant Square values, halfmove clocks, and fullmove numbers.

This function has the same behavior as board1 == board2 and board1.history == board2.history, but is much faster.

>>> board = Board()
>>> board2 = Board()
>>> board.apply(Move(E2, E4))
>>> board2[E2] = None
>>> board2[E4] = Piece(WHITE, PAWN)
>>> board2.turn = BLACK
>>> board2.en_passant_square = E3
>>> board == board2
True
>>> deeply_equal(board, board2)
False
piece_bitboard(board: bulletchess.Board, piece: bulletchess.Piece) bulletchess.Bitboard#

Gets a Bitboard of squares with the given Piece on the given Board.

>>> from bulletchess import *
>>> piece = Piece(WHITE, PAWN)
>>> board = Board()
>>> bb = piece_bitboard(board, piece)
>>> print(bb)
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 
>>> bb == board[WHITE, PAWN]
True
unoccupied_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explict alias for indexing a Board with None.

Gets a Bitboard of all empty squares on the given Board.

>>> board = Board()
>>> bb = unoccupied_bitboard(board)
>>> print(bb)
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
>>> bb == board[None]
True
white_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with WHITE.

Gets a Bitboard of all squares with a white piece on the given Board.

>>> board = Board()
>>> bb = white_bitboard(board)
>>> print(bb)
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 
>>> bb == board[WHITE]
True
black_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with BLACK.

Gets a Bitboard of all squares with a black piece on the given Board.

>>> board = Board()
>>> bb = black_bitboard(board)
>>> print(bb)
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
>>> bb == board[BLACK]
True
king_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with KING.

Gets a Bitboard of all squares with a king on the given Board.

>>> board = Board()
>>> bb = king_bitboard(board)
>>> print(bb)
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
>>> bb == board[KING]
True
queen_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with QUEEN.

Gets a Bitboard of all squares with a queen on the given Board.

Examples#

>>> board = Board()
>>> bb = queen_bitboard(board)
>>> print(bb)
0 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 
>>> bb == board[QUEEN]
True
bishop_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with BISHOP.

Gets a Bitboard of all squares with a bishop on the given Board.

>>> board = Board()
>>> bb = bishop_bitboard(board)
>>> print(bb)
0 0 1 0 0 1 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 1 0 0 1 0 0 
>>> bb == board[BISHOP]
True
rook_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with ROOK.

Gets a Bitboard of all squares with a rook on the given Board.

>>> board = Board()
>>> bb = rook_bitboard(board)
>>> print(bb)
1 0 0 0 0 0 0 1 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 1 
>>> bb == board[ROOK]
True
pawn_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with PAWN.

Gets a Bitboard of all squares with a pawn on the given Board.

>>> board = Board()
>>> bb = pawn_bitboard(board)
>>> print(bb)
0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 
>>> bb == board[PAWN]
True
knight_bitboard(board: bulletchess.Board) bulletchess.Bitboard#

An explicit alias for indexing a Board with KNIGHT.

Gets a Bitboard of all squares with a knight on the given Board.

>>> board = Board()
>>> bb = knight_bitboard(board)
>>> print(bb)
0 1 0 0 0 0 1 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 1 0 0 0 0 1 0 
>>> bb == board[KNIGHT]
True
>>> 
king_square(board: bulletchess.Board, color: bulletchess.Color) bulletchess.Square#

Gets the Square which has the the king of the specified Color on the given Board.

Raises:

AttributeError if the given Board has multiple kings of the given Color.

>>> board = Board()
>>> king_square(board, WHITE) is E1
True
>>> king_square(board, BLACK) is E8
True