"""
Module to create a chess board.
"""
from collections import Counter
from functools import partial
from typing import Protocol
import chess
import shakmaty_python_binding
from .board_chi import BoardChi, LegalMoveKeyGenerator
from .iboard import IBoard, boardKey, compute_key
from .rusty_board import LegalMoveKeyGeneratorRust, RustyBoardChi
from .utils import FenPlusHistory, fen
[docs]class BoardFactory(Protocol):
def __call__(self, fen_with_history: FenPlusHistory | None = None) -> IBoard: ...
[docs]def create_board_factory(
use_rust_boards: bool = False,
use_board_modification: bool = False,
sort_legal_moves: bool = False,
) -> BoardFactory:
board_factory: BoardFactory
if use_rust_boards:
board_factory = partial(
create_rust_board,
use_board_modification=use_board_modification,
sort_legal_moves=sort_legal_moves,
)
else:
board_factory = partial(
create_board_chi,
use_board_modification=use_board_modification,
sort_legal_moves=sort_legal_moves,
)
return board_factory
[docs]def create_board(
use_rust_boards: bool = False,
use_board_modification: bool = False,
sort_legal_moves: bool = False,
fen_with_history: FenPlusHistory | None = None,
) -> IBoard:
board_factory: BoardFactory = create_board_factory(
use_rust_boards=use_rust_boards,
use_board_modification=use_board_modification,
sort_legal_moves=sort_legal_moves,
)
board: IBoard = board_factory(fen_with_history=fen_with_history)
return board
[docs]def create_board_chi_from_pychess_board(
chess_board: chess.Board,
use_board_modification: bool = False,
sort_legal_moves: bool = False,
) -> BoardChi:
board_key_representation: boardKey = compute_key(
pawns=chess_board.pawns,
knights=chess_board.knights,
bishops=chess_board.bishops,
rooks=chess_board.rooks,
queens=chess_board.queens,
kings=chess_board.kings,
turn=chess_board.turn,
castling_rights=chess_board.castling_rights,
ep_square=chess_board.ep_square,
white=chess_board.occupied_co[chess.WHITE],
black=chess_board.occupied_co[chess.BLACK],
promoted=chess_board.promoted,
fullmove_number=chess_board.fullmove_number,
halfmove_clock=chess_board.halfmove_clock,
)
legal_moves: LegalMoveKeyGenerator = LegalMoveKeyGenerator(
chess_board=chess_board, sort_legal_moves=sort_legal_moves
)
board: BoardChi = BoardChi(
chess_board=chess_board,
compute_board_modification=use_board_modification,
fast_representation_=board_key_representation,
legal_moves_=legal_moves,
)
return board
[docs]def create_board_chi(
fen_with_history: FenPlusHistory | None = None,
use_board_modification: bool = False,
sort_legal_moves: bool = False,
) -> BoardChi:
"""
Create a chipiron chess board.
Args:
use_board_modification (bool): whether to use the board modification
fen_with_history (FenPlusMoves | None): The BoardWithHistory that contains a fen and the subsequent moves.
The FEN (Forsyth-Edwards Notation) string representing the board position. If None, the starting position
is used.
Returns:
BoardChi: The created chess board.
"""
chess_board: chess.Board
current_fen: fen
if fen_with_history is not None:
current_fen = fen_with_history.current_fen
chess_board = chess.Board(fen=current_fen)
chess_board.move_stack = [
chess.Move.from_uci(move) for move in fen_with_history.historical_moves
]
chess_board._stack = fen_with_history.historical_boards
else:
chess_board = chess.Board()
board: BoardChi = create_board_chi_from_pychess_board(
chess_board=chess_board,
use_board_modification=use_board_modification,
sort_legal_moves=sort_legal_moves,
)
return board
[docs]def create_rust_board(
fen_with_history: FenPlusHistory | None = None,
use_board_modification: bool = False,
sort_legal_moves: bool = False,
) -> RustyBoardChi:
"""
Create a rust chess board.
Args:
use_board_modification (bool): whether to use the board modification
board_with_history (FenPlusMoves | None): The BoardWithHistory that contains a fen and the subsequent moves.
The FEN (Forsyth-Edwards Notation) string representing the board position. If None, the starting position
is used.
Returns:
RustyBoardChi: The created chess board.
"""
current_fen: fen
chess_rust_binding: shakmaty_python_binding.MyChess
if fen_with_history is not None:
current_fen = fen_with_history.current_fen
chess_rust_binding = shakmaty_python_binding.MyChess(_fen_start=current_fen)
else:
chess_rust_binding = shakmaty_python_binding.MyChess(
_fen_start=chess.STARTING_FEN
)
pawns: int = chess_rust_binding.pawns()
knights: int = chess_rust_binding.knights()
bishops: int = chess_rust_binding.bishops()
rooks: int = chess_rust_binding.rooks()
queens: int = chess_rust_binding.queens()
kings: int = chess_rust_binding.kings()
turn: bool = bool(chess_rust_binding.turn())
white: int = chess_rust_binding.white()
black: int = chess_rust_binding.black()
ep_square_int: int = chess_rust_binding.ep_square()
promoted: int = chess_rust_binding.promoted()
castling_rights: int = chess_rust_binding.castling_rights()
if ep_square_int == -1:
ep_square = None
else:
ep_square = ep_square_int
board_key_representation: boardKey = compute_key(
pawns=pawns,
knights=knights,
bishops=bishops,
rooks=rooks,
queens=queens,
kings=kings,
turn=turn,
castling_rights=castling_rights,
ep_square=ep_square,
white=white,
black=black,
promoted=promoted,
fullmove_number=chess_rust_binding.fullmove_number(),
halfmove_clock=chess_rust_binding.halfmove_clock(),
)
legal_moves: LegalMoveKeyGeneratorRust = LegalMoveKeyGeneratorRust(
chess_rust_binding=chess_rust_binding,
generated_moves=chess_rust_binding.legal_moves(),
sort_legal_moves=sort_legal_moves,
)
rusty_board_chi: RustyBoardChi = RustyBoardChi(
chess_=chess_rust_binding,
compute_board_modification=use_board_modification,
rep_to_count=Counter(),
fast_representation_=board_key_representation,
pawns_=pawns,
knights_=knights,
kings_=kings,
rooks_=rooks,
queens_=queens,
bishops_=bishops,
black_=black,
white_=white,
turn_=turn,
ep_square_=ep_square,
castling_rights_=castling_rights,
promoted_=promoted,
legal_moves_=legal_moves,
)
if fen_with_history is not None:
rusty_board_chi.move_stack = fen_with_history.historical_moves
return rusty_board_chi