Skip to content

Baseboard/Board: add method to count total number of pieces #1140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
kraktus opened this issue Feb 21, 2025 · 2 comments
Open

Baseboard/Board: add method to count total number of pieces #1140

kraktus opened this issue Feb 21, 2025 · 2 comments

Comments

@kraktus
Copy link
Contributor

kraktus commented Feb 21, 2025

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).

@Torom
Copy link

Torom commented Mar 26, 2025

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

@Phillyclause89
Copy link

Phillyclause89 commented Apr 25, 2025

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants