Baseboard/Board: add method to count total number of pieces
Unless I've missed it, not possible to and useful when working with tbs for example. My goto implementation for now is
len(chess.SquareSet(board.occupied))
not sure about the name, baseboard.nb_pieces, baseboard.total_nb_pieces, baseboard.pieces_count (but could be thought as the count of pieces per type).
I also think that a function for this could be useful, because not every user comes up with the best implementation for this.
This seems to be the best method, python-chess also uses it internally:
chess.popcount(board.occupied)
In my test, it is almost 5 times faster than your method:
import time
import chess
board = chess.Board()
t = time.perf_counter()
[len(chess.SquareSet(board.occupied)) for _ in range(10_000_000)]
total = time.perf_counter() - t
print('Test1:', total)
t = time.perf_counter()
[chess.popcount(board.occupied) for _ in range(10_000_000)]
total = time.perf_counter() - t
print('Test2:', total)
Test1: 3.1755944349997662
Test2: 0.6580440879997695
I also found myself wanting a pieces_count member that I could get at while using your api. I ended up going with a solution that uses int.bitcount: https://github.com/Phillyclause89/ChessMoveHeatmap/blob/e482a42978f824ab477e4c0e2ee2467e004e5b71/chmengine/utils/init.py#L12
# Python 3.8+ has bit_count(); otherwise count the '1's in the binary repr
try:
_bit_count: Callable[[int], int] = int.bit_count
except AttributeError:
def _bit_count(occ: int) -> int:
return bin(occ).count('1')
def pieces_count_from_board(board: Board) -> int:
"""Return the number of pieces on the board
This uses the internal bitboard to count occupied squares in O(1) time.
On Python ≥ 3.8 it calls `int.bit_count()`. On Python 3.7 it falls back
to `bin(...).count('1')` for compatibility.
Parameters
----------
board : chess.Board
A board object to count pieces from
Returns
-------
int
Number of pieces on the board.
Examples
--------
>>> from chess import Board
>>> mate_board = Board('8/2p2p2/4p3/2k5/8/6q1/2K5/1r1q4 w - - 2 59')
>>> pieces_count_from_board(mate_board)
8
>>> pieces_count_from_board(Board())
32
"""
return _bit_count(board.occupied)