Perfect-play Connect-4 solver. More...
#include <BitBully.h>
Public Member Functions | |
| BitBully (const std::filesystem::path &bookPath="") | |
| Construct a solver, optionally loading an opening book. | |
| bool | isBookLoaded () const |
| Was an opening book successfully loaded? | |
| void | resetBook () |
| Discard the currently loaded opening book (if any). | |
| bool | loadBook (const std::filesystem::path &bookPath="") |
| Load an opening book from disk. | |
| int | mtdf (const Board &b, const int firstGuess, const int maxDepth=-1) noexcept |
| Solve a position using the MTD(f) driver. | |
| int | nullWindow (const Board &b, const int maxDepth=-1) noexcept |
| Alternative driver based on a binary search of zero-width windows. | |
| void | resetTranspositionTable () |
| Discard the contents of the transposition table. | |
| auto | getNodeCounter () const |
| Number of nodes visited since resetNodeCounter(). | |
| void | resetNodeCounter () |
| Reset the visited-node counter to zero. | |
| int | negamax (Board b, int alpha, int beta, const int depth, const int maxDepth=-1) noexcept |
| Negamax search with alpha-beta pruning, transposition table and opening book consultation. | |
| auto | scoreMove (const Board &b, const int column, const int firstGuess, const int maxDepth=-1) |
Evaluate the move that drops a stone in column. | |
| auto | scoreMoves (const Board &b, const int maxDepth=-1) |
Evaluate every column move from b. | |
Static Public Member Functions | |
| static int | scoreToMovesLeft (const int score, const Board &b) noexcept |
| Convert a solver score to the number of moves until the game ends. | |
| static int | rollout (Board b) noexcept |
| Cheap evaluation: play out the game using safe heuristic moves. | |
Perfect-play Connect-4 solver.
Maintains a transposition table and (optionally) an opening book between searches so that subsequent calls reuse previously computed information. Scores returned by the engine follow the convention introduced by Pascal Pons:
s means the player to move wins on ply 2 * s - 1 from the current position,s means the player to move loses on ply 2 * |s|,0 indicates a draw.The helper scoreToMovesLeft converts these compact scores back into the actual number of plies remaining.
Definition at line 45 of file BitBully.h.
|
inlineexplicit |
Construct a solver, optionally loading an opening book.
| bookPath | Path to a binary opening-book file. If empty, no book is loaded and isBookLoaded() returns false. |
Definition at line 64 of file BitBully.h.
|
inlinenodiscard |
Number of nodes visited since resetNodeCounter().
Definition at line 248 of file BitBully.h.
|
inline |
Was an opening book successfully loaded?
Definition at line 72 of file BitBully.h.
|
inline |
Load an opening book from disk.
The database type (8-ply vs. 12-ply, with or without distance information) is inferred from the file size.
| bookPath | Path to the book file. Empty paths are a no-op. |
true if a new book is now loaded; false if a book was already loaded or bookPath is empty. Definition at line 87 of file BitBully.h.
|
inlinenoexcept |
Solve a position using the MTD(f) driver.
MTD(f) repeatedly invokes negamax() with zero-width ([beta-1, beta]) windows, tightening the upper and lower bounds until they meet. The firstGuess parameter seeds the initial test value: a good guess (e.g. from a previous shallow search) drastically reduces the number of re-searches.
| b | Position to evaluate. |
| firstGuess | Initial guess for the position's score. |
| maxDepth | Maximum search depth in plies, or -1 for unlimited search (full perfect-play resolution). |
b (or a depth-limited approximation when maxDepth ≥ 0).Definition at line 188 of file BitBully.h.
|
inlinenoexcept |
Negamax search with alpha-beta pruning, transposition table and opening book consultation.
The function combines several enhancements:
maxDepth is hit.| b | Position to evaluate (passed by value — recursion mutates a local copy). |
| alpha | Current lower bound of the search window. |
| beta | Current upper bound of the search window. |
| depth | Plies played from the search root. |
| maxDepth | Maximum total search depth, or -1 for unlimited. |
b in the active player's perspective. Definition at line 274 of file BitBully.h.
|
inlinenoexcept |
Alternative driver based on a binary search of zero-width windows.
Empirically slower than mtdf() in this codebase but useful for cross-checking results.
| b | Position to evaluate. |
| maxDepth | Maximum search depth in plies, or -1 for unlimited search. |
b. Definition at line 221 of file BitBully.h.
|
inline |
Discard the currently loaded opening book (if any).
Definition at line 75 of file BitBully.h.
|
inline |
Reset the visited-node counter to zero.
Definition at line 251 of file BitBully.h.
|
inline |
Discard the contents of the transposition table.
Definition at line 242 of file BitBully.h.
|
inlinestaticnoexcept |
Cheap evaluation: play out the game using safe heuristic moves.
Both players use Board::generateNonLosingMoves() to avoid immediate losses; among multiple non-losing moves the centre-priority heuristic Board::nextMove() picks the next ply. The function terminates as soon as a side reaches a winning position or runs out of non-losing replies.
| b | Position to evaluate. Passed by value because the rollout mutates a local copy. |
b. Definition at line 139 of file BitBully.h.
|
inline |
Evaluate the move that drops a stone in column.
Plays the move on a copy of b and runs mtdf() on the resulting position, then negates the score so that it is reported from the perspective of the player to move in b.
| b | Current position. |
| column | Column index of the move to evaluate. |
| firstGuess | Seed value for MTD(f). |
| maxDepth | Search depth limit, or -1 for unlimited search. |
-1000 if column is not a legal move. Definition at line 476 of file BitBully.h.
|
inline |
Evaluate every column move from b.
Calls scoreMove() for each of the N_COLUMNS columns. Illegal moves are reported with the sentinel score -1000.
| b | Current position. |
| maxDepth | Search depth limit, or -1 for unlimited search. |
Definition at line 499 of file BitBully.h.
|
inlinestaticnoexcept |
Convert a solver score to the number of moves until the game ends.
| score | The solver score (positive = current player wins, negative = current player loses, 0 = draw). |
| b | The board state for which the score was computed. |
The encoding maps the absolute score to a final-ply count:
\[ \text{plies\_left}(s, b) = \begin{cases} \text{movesLeft}(b) & s = 0 \\ \text{movesLeft}(b) - \bigl(2(|s| - 1) + \delta\bigr) & s \ne 0 \end{cases} \]
where \(\delta \in \{0, 1\}\) accounts for the parity of the side to move (winning move falls on an even or odd ply).
Definition at line 115 of file BitBully.h.