bitbully_core
Low-level pybind11 bindings for BitBully (Connect-4 solver).
This module exposes the core C++ engine via pybind11. It provides:
- class BoardCore: Fast bitboard-based Connect-4 position representation.
- class BitBullyCore : Perfect-play solver (MTD(f), negamax, null-window) with optional opening book.
- class OpeningBookCore: Opening book reader / lookup helper.
- enum Player: Player enum used by the engine.
- data N_COLUMNS, data N_ROWS: Board dimensions (standard Connect-4: 7x6).
Notes
These APIs are low-level and mirror the underlying C++ engine closely.
Most users should prefer the high-level Python wrapper (e.g. bitbully.Board,
bitbully.BitBully) unless they need maximum control or performance.
Example
Create a board, score moves, and pick a best move:
import bitbully.bitbully_core as bbc
board = bbc.BoardCore()
assert board.play("334411")
assert isinstance(str(board), str) and str(board) != ""
solver = bbc.BitBullyCore()
scores = solver.scoreMoves(board)
# One score per column.
assert len(scores) == 7
# Pick best column by score (ties resolved by first max).
best_col = max(range(7), key=scores.__getitem__)
assert 0 <= best_col < 7
Classes:
| Name | Description |
|---|---|
BitBullyCore |
Perfect-play Connect-4 solver implemented in C++. |
BoardCore |
Low-level Connect-4 board representation (bitboard-based). |
OpeningBookCore |
Opening book reader and lookup helper. |
Player |
Player identifiers used by the engine. |
Attributes:
| Name | Type | Description |
|---|---|---|
N_COLUMNS |
int
|
Number of columns of the standard Connect-4 board (7). |
N_ROWS |
int
|
Number of rows of the standard Connect-4 board (6). |
N_COLUMNS
module-attribute
N_COLUMNS: int
Number of columns of the standard Connect-4 board (7).
Example
Read the board dimensions:
-
BitBully API Reference
bitbully_core
N_ROWS
module-attribute
N_ROWS: int
Number of rows of the standard Connect-4 board (6).
Example
Read the board dimensions:
-
BitBully API Reference
bitbully_core
__all__
module-attribute
__all__: list[str] = ['N_COLUMNS', 'N_ROWS', 'BitBullyCore', 'BoardCore', 'OpeningBookCore', 'Player']
BitBullyCore
Perfect-play Connect-4 solver implemented in C++.
The solver evaluates positions from the perspective of the side to move. It supports multiple search methods and optional opening-book acceleration.
Notes
- Column indices are 0..6 (left to right).
- Scores are engine-defined integers; higher is better for the player to move.
- When an opening book is loaded, early-game positions can be evaluated in constant time.
Example
Score all legal moves in a position:
import bitbully.bitbully_core as bbc
import bitbully_databases as bbd
db_path = bbd.BitBullyDatabases.get_database_path("default")
board = bbc.BoardCore()
assert board.play(6 * "3")
solver = bbc.BitBullyCore(db_path)
scores = solver.scoreMoves(board)
# Scores has length 7 (one per column).
assert len(scores) == 7
# Pick best column by score.
best_col = max(range(7), key=scores.__getitem__)
print("Best column:", best_col)
- BitBully API Reference
Methods:
| Name | Description |
|---|---|
getNodeCounter |
Return the number of visited nodes since the last reset. |
isBookLoaded |
Return whether an opening book is currently loaded. |
loadBook |
Load an opening book from a file path. |
mtdf |
Evaluate a position using the MTD(f) algorithm. |
negamax |
Evaluate a position using negamax (alpha-beta) search. |
nullWindow |
Evaluate a position using a null-window search. |
resetBook |
Unload the currently loaded opening book (if any). |
resetNodeCounter |
Reset the internal node counter. |
resetTranspositionTable |
Clear the internal transposition table. |
scoreMove |
Evaluate a single move in the given position. |
scoreMoves |
Evaluate all columns (0..6) in the given position. |
getNodeCounter
getNodeCounter() -> int
Return the number of visited nodes since the last reset.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of search nodes visited since the last call to BitBullyCore.resetNodeCounter. |
Example
Count how many nodes a search visited:
Source code in src/bitbully/bitbully_core.pyi
isBookLoaded
isBookLoaded() -> bool
Return whether an opening book is currently loaded.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Check if the solver currently uses an opening book:
Source code in src/bitbully/bitbully_core.pyi
loadBook
Load an opening book from a file path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
PathLike[str] | str
|
Path to the opening book file. |
...
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Load a book and verify it is active:
Source code in src/bitbully/bitbully_core.pyi
mtdf
mtdf(board: BoardCore, first_guess: int) -> int
Evaluate a position using the MTD(f) algorithm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Position to evaluate. |
required |
|
int
|
Initial guess for the score (often 0). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Evaluation score for the side to move. |
Example
Evaluate a position using MTD(f) (six moves in the center column):
Expected output:Source code in src/bitbully/bitbully_core.pyi
negamax
Evaluate a position using negamax (alpha-beta) search.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Position to evaluate. |
required |
|
int
|
Alpha bound. |
required |
|
int
|
Beta bound. |
required |
|
int
|
Search depth in plies. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Evaluation score for the side to move. |
Example
Run a negamax call with an alpha-beta window:
Expected output:Source code in src/bitbully/bitbully_core.pyi
nullWindow
Evaluate a position using a null-window search.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Position to evaluate. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Evaluation score for the side to move. |
Example
Use null-window search:
Expected output:Source code in src/bitbully/bitbully_core.pyi
resetBook
Unload the currently loaded opening book (if any).
Example
Unload a book:
import bitbully.bitbully_core as bbc
import bitbully_databases as bbd
db_path = bbd.BitBullyDatabases.get_database_path("default")
solver = bbc.BitBullyCore()
_ = solver.loadBook(db_path) # replace with your file
assert solver.isBookLoaded() is True
solver.resetBook()
assert solver.isBookLoaded() is False
Source code in src/bitbully/bitbully_core.pyi
resetNodeCounter
Reset the internal node counter.
Example
Reset node counter between searches:
-
BitBully API Reference
bitbully_coreBitBullyCoregetNodeCounter
Source code in src/bitbully/bitbully_core.pyi
resetTranspositionTable
Clear the internal transposition table.
Example
Clear cached results (useful for benchmarking):
Source code in src/bitbully/bitbully_core.pyi
scoreMove
Evaluate a single move in the given position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Current position. |
required |
|
int
|
Column index (0-6) of the move to evaluate. |
required |
|
int
|
Initial guess for the score (often 0). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Evaluation score of playing the move in |
Example
Score one candidate move:
Expected output:Example
Score one candidate move and verify it matches the per-column score vector:
import bitbully.bitbully_core as bbc
solver = bbc.BitBullyCore()
board = bbc.BoardCore()
assert board.setBoard([3, 4, 1, 1, 0, 2, 2, 2])
scores = solver.scoreMoves(board)
# Column 4 is known to be best in this position.
one = solver.scoreMove(board, column=4, first_guess=0)
assert one == scores[4] == 3
-
BitBully API Reference
solverBitBullyscore_move
Source code in src/bitbully/bitbully_core.pyi
scoreMoves
Evaluate all columns (0..6) in the given position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Current position. |
required |
Returns:
| Type | Description |
|---|---|
list[int]
|
list[int]: A list of length 7 with per-column scores. Illegal moves (full columns) are included and use an engine-defined sentinel value. |
Example
Score all moves and pick the best:
Example
Score all columns and compare against a known expected score vector:
Example
Illegal moves are included and use the engine sentinel value (-1000):
import bitbully.bitbully_core as bbc
solver = bbc.BitBullyCore()
board = bbc.BoardCore()
assert board.setBoard([3, 3, 3, 3, 3, 3, 4, 2])
scores = solver.scoreMoves(board)
assert scores == [-2, -2, 2, -1000, -2, 1, -1]
# Column 3 is full here (sentinel score).
assert board.isLegalMove(3) is False
assert scores[3] == -1000
Source code in src/bitbully/bitbully_core.pyi
BoardCore
Low-level Connect-4 board representation (bitboard-based).
This class is optimized for speed and is the main input type for the solver. It supports playing moves, mirroring, hashing/UIDs, win checks, and move generation.
Notes
- Column indices are 0..6 (left to right).
- The side to move is part of the position state.
- Many methods correspond 1:1 to C++ engine functions.
Example
Create a board, play a sequence, and print:
Expected output:-
BitBully API Reference
bitbully_core
- BitBully API Reference
-
BitBully API Reference
bitbully_core
Methods:
| Name | Description |
|---|---|
__eq__ |
Compare two boards for exact position equality. |
__ne__ |
Compare two boards for inequality. |
allPositions |
Generate all reachable positions from the current board up to a ply limit. |
copy |
Create a deep copy of the board. |
countTokens |
Return the number of tokens currently on the board. |
doubleThreat |
Compute double-threat information (engine-specific). |
findThreats |
Compute threat information (engine-specific). |
generateNonLosingMoves |
Return a bitmask of non-losing legal moves (engine definition). |
getColumnHeight |
Return the number of tokens in the given column. |
hasWin |
Check whether the player who made the last move has a connect-four. |
hash |
Return a hash of the current position. |
isLegalMove |
Check whether playing in |
isValid |
Check whether a 7x6 column-major token grid is valid. |
legalMoves |
Return legal moves as a list of column indices. |
legalMovesMask |
Return the legal moves as a bitmask. |
mirror |
Return the horizontally mirrored position. |
movesLeft |
Return the number of empty cells remaining. |
playMoveOnCopy |
Return a new board with |
popCountBoard |
Return the number of occupied cells (popcount of the token bitboard). |
randomBoard |
Generate a random reachable position by playing random moves. |
toArray |
Return the current position as a 7x6 column-major token grid. |
toHuffman |
Encode the current position into the engine's Huffman representation. |
toString |
Return a human-readable ASCII rendering of the board. |
uid |
Return a deterministic unique identifier for the current position. |
Attributes:
| Name | Type | Description |
|---|---|---|
__hash__ |
None
|
|
__eq__
Compare two boards for exact position equality.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Other board. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Compare two independently built boards:
Source code in src/bitbully/bitbully_core.pyi
__ne__
Compare two boards for inequality.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Other board. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Build two different positions and compare:
Source code in src/bitbully/bitbully_core.pyi
allPositions
Generate all reachable positions from the current board up to a ply limit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Maximum total token count for generated positions. |
required |
|
bool
|
If |
required |
Returns:
| Type | Description |
|---|---|
list[BoardCore]
|
list[BoardCore]: List of generated positions. |
Example
Enumerate all positions with exactly 2 tokens from the empty board:
Expected output:Source code in src/bitbully/bitbully_core.pyi
copy
copy() -> BoardCore
Create a deep copy of the board.
Returns:
| Name | Type | Description |
|---|---|---|
BoardCore |
BoardCore
|
Independent copy of the current position. |
Example
Create a board, copy it, and verify that both represent the same position:
import bitbully.bitbully_core as bbc
# Create a board from a compact move string.
board = bbc.BoardCore()
assert board.play("33333111")
# Create an independent copy of the current position.
board_copy = board.copy()
# Both boards represent the same position and are considered equal.
assert board == board_copy
assert board.uid() == board_copy.uid()
assert board.toString() == board_copy.toString()
# Display the board state.
print(board.toString())
Source code in src/bitbully/bitbully_core.pyi
countTokens
countTokens() -> int
Return the number of tokens currently on the board.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Token count (0-42). |
Example
Count tokens after playing a move string:
Source code in src/bitbully/bitbully_core.pyi
doubleThreat
Compute double-threat information (engine-specific).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Move mask / move set parameter as expected by the engine.
A typical input is the result of |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Engine-defined bitmask/encoding of detected double threats. |
Source code in src/bitbully/bitbully_core.pyi
findThreats
Compute threat information (engine-specific).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Move mask / move set parameter as expected by the engine.
A typical input is the result of |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Engine-defined bitmask/encoding of detected threats. |
Source code in src/bitbully/bitbully_core.pyi
generateNonLosingMoves
generateNonLosingMoves() -> int
Return a bitmask of non-losing legal moves (engine definition).
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Bitmask encoding non-losing moves for the side to move. |
Example
Generate non-losing moves and compare with all legal moves:
Source code in src/bitbully/bitbully_core.pyi
getColumnHeight
Return the number of tokens in the given column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Column index (0-6). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of tokens in the column (0-6). |
Example
Check column heights after some moves:
import bitbully.bitbully_core as bbc
board = bbc.BoardCore()
assert board.play("3332211" + 6 * "5")
assert board.getColumnHeight(0) == 0
assert board.getColumnHeight(1) == 2
assert board.getColumnHeight(2) == 2
assert board.getColumnHeight(3) == 3
assert board.getColumnHeight(4) == 0
assert board.getColumnHeight(5) == 6
assert board.getColumnHeight(6) == 0
Source code in src/bitbully/bitbully_core.pyi
hasWin
hasWin() -> bool
Check whether the player who made the last move has a connect-four.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Play a winning sequence and check that the last mover has a win:
Source code in src/bitbully/bitbully_core.pyi
hash
hash() -> int
Return a hash of the current position.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Hash value suitable for hash tables / transposition tables. |
Example
Hashes match for identical positions and differ after divergence:
Source code in src/bitbully/bitbully_core.pyi
isLegalMove
Check whether playing in column is legal (in-range and not full).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Column index (0-6). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Check legality before playing:
Source code in src/bitbully/bitbully_core.pyi
isValid
staticmethod
Check whether a 7x6 column-major token grid is valid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
list[list[int]]
|
Column-major 7x6 grid ( |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Validate a board grid before setting it:
Source code in src/bitbully/bitbully_core.pyi
legalMoves
Return legal moves as a list of column indices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
bool
|
If |
required |
|
bool
|
If |
required |
Returns:
| Type | Description |
|---|---|
list[int]
|
list[int]: List of legal column indices. |
Example
Get ordered legal moves (center-first):
Expected output:Source code in src/bitbully/bitbully_core.pyi
legalMovesMask
legalMovesMask() -> int
Return the legal moves as a bitmask.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Bitmask encoding the set of legal moves (engine bitboard format). |
Example
Get the move mask and verify it is non-zero on non-full boards:
Source code in src/bitbully/bitbully_core.pyi
mirror
mirror() -> BoardCore
Return the horizontally mirrored position.
Returns:
| Name | Type | Description |
|---|---|---|
BoardCore |
BoardCore
|
Mirrored board (column 0 <-> 6, 1 <-> 5, 2 <-> 4). |
Example
Mirror twice returns the original position:
Source code in src/bitbully/bitbully_core.pyi
movesLeft
movesLeft() -> int
Return the number of empty cells remaining.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Remaining moves until the board is full (0-42). |
Example
Confirm moves left after some moves:
Source code in src/bitbully/bitbully_core.pyi
playMoveOnCopy
Return a new board with mv applied, leaving the original unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Column index (0-6). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
BoardCore |
BoardCore
|
New board after the move. |
Example
Try a move without mutating the original board:
Source code in src/bitbully/bitbully_core.pyi
popCountBoard
popCountBoard() -> int
Return the number of occupied cells (popcount of the token bitboard).
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of occupied cells (0-42). |
Example
Compare popCountBoard() with countTokens():
Source code in src/bitbully/bitbully_core.pyi
randomBoard
staticmethod
Generate a random reachable position by playing random moves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Number of moves (tokens) to play (0-42). |
required |
|
bool
|
If |
required |
Returns:
| Type | Description |
|---|---|
tuple[BoardCore, list[int]]
|
tuple[BoardCore, list[int]]: |
Example
Create a random 8-ply position and show the move sequence:
Source code in src/bitbully/bitbully_core.pyi
toArray
Return the current position as a 7x6 column-major token grid.
Returns:
| Type | Description |
|---|---|
list[list[int]]
|
list[list[int]]: Column-major grid (7 columns x 6 rows). |
Example
Convert to an array and inspect dimensions:
Source code in src/bitbully/bitbully_core.pyi
toHuffman
toHuffman() -> int
Encode the current position into the engine's Huffman representation.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Huffman-encoded position key used by the opening books. |
Example
Compute a Huffman key (only defined for certain positions):
Expected output:Source code in src/bitbully/bitbully_core.pyi
toString
toString() -> str
Return a human-readable ASCII rendering of the board.
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Multi-line 6x7 grid representation. |
Example
Print a board:
Expected output:Source code in src/bitbully/bitbully_core.pyi
uid
uid() -> int
Return a deterministic unique identifier for the current position.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
UID derived from the position (tokens + side to move). |
Example
Use uid() as a stable key for caching:
Source code in src/bitbully/bitbully_core.pyi
OpeningBookCore
Opening book reader and lookup helper.
Opening books map a compact position key (Huffman encoding) to an engine score, optionally including distance-to-win information.
Example
Load a book and check whether a position is contained:
-
BitBully API Reference
bitbully_core
Methods:
| Name | Description |
|---|---|
convertValue |
Convert a stored book value to an engine score for the given board. |
getBoardValue |
Lookup a board position in the opening book and return its value. |
getBook |
Return the raw opening book table. |
getBookSize |
Return the number of entries in the opening book. |
getEntry |
Return a single raw entry by index. |
getNPly |
Return the ply depth of the opening book. |
init |
Reinitialize the opening book with new settings. |
isInBook |
Check whether a position exists in the opening book. |
readBook |
Read an opening book file into a raw table. |
convertValue
Convert a stored book value to an engine score for the given board.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Raw value stored in the book table. |
required |
|
BoardCore
|
Board used to interpret the value. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Converted score in the engine's scoring convention. |
Example
Convert a raw entry value using the current board context:
import bitbully.bitbully_core as bbc
import bitbully_databases as bbd
db_path = bbd.BitBullyDatabases.get_database_path("default")
board = bbc.BoardCore()
book = bbc.OpeningBookCore(db_path) # replace with your file
key, raw_val = book.getEntry(0)
score = book.convertValue(raw_val, board)
print("Converted score:", score)
Source code in src/bitbully/bitbully_core.pyi
getBoardValue
Lookup a board position in the opening book and return its value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Position to query. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Book value converted to the engine's scoring convention. |
Example
Query a position's book value:
import bitbully.bitbully_core as bbc
import bitbully_databases as bbd
db_path = bbd.BitBullyDatabases.get_database_path("default")
board = bbc.BoardCore()
assert board.play("333331111555")
book = bbc.OpeningBookCore(db_path) # replace with your file
if book.isInBook(board):
print("Value:", book.getBoardValue(board))
Source code in src/bitbully/bitbully_core.pyi
getBook
Return the raw opening book table.
Returns:
| Type | Description |
|---|---|
list[tuple[int, int]]
|
list[tuple[int, int]]: List of |
Example
Access the raw table and inspect the first entry:
Expected output:Source code in src/bitbully/bitbully_core.pyi
getBookSize
getBookSize() -> int
Return the number of entries in the opening book.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of stored positions. |
Example
Print the number of stored positions:
Expected output:Source code in src/bitbully/bitbully_core.pyi
getEntry
Return a single raw entry by index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Entry index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
tuple[int, int]: The |
Example
Read a single entry:
Expected output:Source code in src/bitbully/bitbully_core.pyi
getNPly
getNPly() -> int
Return the ply depth of the opening book.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Ply depth (e.g., 8 or 12). |
Example
Print the book depth:
Expected output:Source code in src/bitbully/bitbully_core.pyi
init
Reinitialize the opening book with new settings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
PathLike
|
Path to the book file. |
required |
|
bool
|
Whether this is an 8-ply book. |
required |
|
bool
|
Whether values include distance-to-win information. |
required |
Example
Reinitialize an existing instance:
Source code in src/bitbully/bitbully_core.pyi
isInBook
Check whether a position exists in the opening book.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
BoardCore
|
Position to check. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Check membership before lookup:
import bitbully.bitbully_core as bbc
import bitbully_databases as bbd
db_path = bbd.BitBullyDatabases.get_database_path("default")
board = bbc.BoardCore()
assert board.play("334411")
book = bbc.OpeningBookCore(db_path)
in_book = book.isInBook(board)
if in_book:
_ = book.getBoardValue(board)
assert isinstance(in_book, bool)
Source code in src/bitbully/bitbully_core.pyi
readBook
staticmethod
readBook(filename: PathLike, with_distances: bool = True, is_8ply: bool = False) -> list[tuple[int, int]]
Read an opening book file into a raw table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
PathLike
|
Path to the book file. |
required |
|
bool
|
If |
True
|
|
bool
|
If |
False
|
Returns:
| Type | Description |
|---|---|
list[tuple[int, int]]
|
list[tuple[int, int]]: List of |
Example
Read the raw book table:
Expected output:Source code in src/bitbully/bitbully_core.pyi
Player
flowchart TD
src.bitbully.bitbully_core.Player[Player]
click src.bitbully.bitbully_core.Player href "" "src.bitbully.bitbully_core.Player"
Player identifiers used by the engine.
Example
Inspect numeric values used by the engine:
-
BitBully API Reference
bitbully_core
Attributes:
| Name | Type | Description |
|---|---|---|
P_EMPTY |
int
|
Empty cell marker (no token). |
P_RED |
int
|
Player 2 / Red token. |
P_YELLOW |
int
|
Player 1 / Yellow token. |