Skip to main content

Highโ€‘performance C++ MCTS (AlphaZero & MuZero) with Tree Reuse and Avg Depth for triangular games

Project description

CI PyPI Coverage Status License: MIT Python Version

TriMCTS

TriMCTS Logo

TriMCTS is an installable Python package providing C++ bindings for Monte Carlo Tree Search, supporting both AlphaZero and MuZero paradigms, optimized for triangular grid games like the one in trianglengin.

๐Ÿ”‘ Key Features

  • High-performance C++ core implementation.
  • Seamless Python integration via Pybind11.
  • Supports AlphaZero-style evaluation (policy/value from state).
  • Batched Network Evaluations: Efficiently calls the Python network's evaluate_batch method during search for improved performance, especially with GPUs.
  • MCTS Tree Reuse: Significantly speeds up sequential MCTS calls (e.g., during self-play) by reusing the relevant subtree from the previous search step. The C++ core manages the tree lifetime via opaque handles (py::capsule) passed between Python calls.
  • (Planned) Supports MuZero-style evaluation (initial inference + recurrent inference).
  • Configurable search parameters (simulation count, PUCT, discount factor, Dirichlet noise, batch size).
  • Designed for use with external Python game state objects and network evaluators.
  • Type-hinted Python API (py.typed compliant).

๐Ÿš€ Installation

# From PyPI (once published)
pip install trimcts

# For development (from cloned repo root)
# Ensure you clean previous builds if you encounter issues:
# rm -rf build/ src/trimcts.egg-info/ dist/ src/trimcts/trimcts_cpp.*.so
pip install -e .[dev]

๐Ÿ’ก Usage Example (AlphaZero Style with Tree Reuse)

import time
import numpy as np
import torch # Added import
# Use the actual GameState if trianglengin is installed
try:
    from trianglengin import GameState, EnvConfig
    HAS_TRIANGLENGIN = True
except ImportError:
    # Define minimal mocks if trianglengin is not available
    class GameState: # type: ignore
        def __init__(self, *args, **kwargs): self.current_step = 0
        def is_over(self): return False
        def copy(self): return self
        def step(self, action): return 0.0, False
        def get_outcome(self): return 0.0
        def valid_actions(self): return [0, 1]
    class EnvConfig: pass # type: ignore
    HAS_TRIANGLENGIN = False

# Assuming alphatriangle is installed and provides these:
# from alphatriangle.nn import NeuralNetwork # Example network wrapper
# from alphatriangle.config import ModelConfig, TrainConfig

from trimcts import run_mcts, SearchConfiguration, AlphaZeroNetworkInterface

# --- Mock Neural Network (same as before) ---
class MockNeuralNetwork:
    def __init__(self, *args, **kwargs):
        self.model = torch.nn.Module() # Dummy model
        print("MockNeuralNetwork initialized.")

    def evaluate_state(self, state: GameState) -> tuple[dict[int, float], float]:
        valid_actions = state.valid_actions()
        if not valid_actions: return {}, 0.0
        policy = {action: 1.0 / len(valid_actions) for action in valid_actions}
        value = 0.5
        return policy, value

    def evaluate_batch(self, states: list[GameState]) -> list[tuple[dict[int, float], float]]:
        print(f"  Mock evaluate_batch called with {len(states)} states.")
        return [self.evaluate_state(s) for s in states]

    def load_weights(self, path): print(f"Mock: Pretending to load weights from {path}")
    def to(self, device): print(f"Mock: Pretending to move model to {device}"); return self
# --- End Mock Neural Network ---

# --- AlphaZero Wrapper (same as before) ---
class MyAlphaZeroWrapper(AlphaZeroNetworkInterface):
    def __init__(self, model_path: str | None = None):
        self.network = MockNeuralNetwork()
        if model_path: self.network.load_weights(model_path)
        self.network.model.eval()
        print("MyAlphaZeroWrapper initialized.")

    def evaluate_state(self, state: GameState) -> tuple[dict[int, float], float]:
        print(f"Python: Evaluating SINGLE state step {state.current_step}")
        policy_map, value = self.network.evaluate_state(state)
        print(f"Python: Single evaluation result - Policy keys: {len(policy_map)}, Value: {value:.4f}")
        return policy_map, value

    def evaluate_batch(self, states: list[GameState]) -> list[tuple[dict[int, float], float]]:
        print(f"Python: Evaluating BATCH of {len(states)} states.")
        results = self.network.evaluate_batch(states)
        print(f"Python: Batch evaluation returned {len(results)} results.")
        return results

# --- Simulation Loop Example ---
env_config = EnvConfig()
if HAS_TRIANGLENGIN:
    env_config.ROWS = 3
    env_config.COLS = 3
    env_config.NUM_SHAPE_SLOTS = 1
    env_config.PLAYABLE_RANGE_PER_ROW = [(0,3), (0,3), (0,3)]

game_state = GameState(config=env_config, initial_seed=42)
network_wrapper = MyAlphaZeroWrapper()

mcts_config = SearchConfiguration()
mcts_config.max_simulations = 50
mcts_config.mcts_batch_size = 8

# --- Tree Reuse Variables ---
mcts_tree_handle = None # Start with no tree
last_action = -1        # No previous action initially

print("--- Running Self-Play Loop with Tree Reuse ---")
max_episode_steps = 10
for step in range(max_episode_steps):
    if game_state.is_over():
        print(f"\nGame over at step {step}. Final Score: {game_state.game_score()}")
        break

    print(f"\n--- Step {step} ---")
    print(f"Current State Step: {game_state.current_step}")
    print(f"Passing tree handle: {'Yes' if mcts_tree_handle else 'No'}")
    print(f"Passing last action: {last_action}")

    # Run MCTS, passing the handle and last action
    # It returns visit counts AND the new handle
    start_time = time.time()
    visit_counts, mcts_tree_handle = run_mcts(
        root_state=game_state,
        network_interface=network_wrapper,
        config=mcts_config,
        previous_tree_handle=mcts_tree_handle, # Pass handle from previous step
        last_action=last_action               # Pass action that led to current state
    )
    end_time = time.time()
    print(f"MCTS Result (Visit Counts) after {end_time - start_time:.3f} seconds:")
    print(visit_counts)
    print(f"Received new tree handle: {'Present' if mcts_tree_handle else 'None'}")

    # Select best action based on visits
    if not visit_counts:
        print("MCTS returned no visits. Ending episode.")
        break
    best_action = max(visit_counts, key=visit_counts.get)
    print(f"Selected Action: {best_action}")

    # Store the selected action for the *next* MCTS call
    last_action = best_action

    # Apply the action to the game state
    reward, done = game_state.step(best_action)
    print(f"Step Reward: {reward:.3f}, Done: {done}")

else:
     print(f"\nEpisode finished after {max_episode_steps} steps.")

# The mcts_tree_handle (a py::capsule) will be automatically garbage collected
# by Python when it goes out of scope, triggering the C++ destructor.
print("\n--- End of Simulation ---")

(MuZero example will be added later)

๐Ÿ“‚ Project Structure

trimcts/
โ”œโ”€โ”€ .github/workflows/      # CI configuration (e.g., ci_cd.yml)
โ”œโ”€โ”€ src/trimcts/            # Python package source ([src/trimcts/README.md](src/trimcts/README.md))
โ”‚   โ”œโ”€โ”€ cpp/                # C++ source code ([src/trimcts/cpp/README.md](src/trimcts/cpp/README.md))
โ”‚   โ”‚   โ”œโ”€โ”€ CMakeLists.txt  # CMake build script for C++ part
โ”‚   โ”‚   โ”œโ”€โ”€ bindings.cpp    # Pybind11 bindings
โ”‚   โ”‚   โ”œโ”€โ”€ config.h        # C++ configuration struct
โ”‚   โ”‚   โ”œโ”€โ”€ mcts.cpp        # C++ MCTS implementation (Node, simulation loop)
โ”‚   โ”‚   โ”œโ”€โ”€ mcts.h          # C++ MCTS header
โ”‚   โ”‚   โ”œโ”€โ”€ mcts_manager.cpp # C++ MCTS Tree Manager implementation
โ”‚   โ”‚   โ”œโ”€โ”€ mcts_manager.h  # C++ MCTS Tree Manager header (handles lifetime)
โ”‚   โ”‚   โ”œโ”€โ”€ python_interface.h # C++ helpers for Python interaction
โ”‚   โ”‚   โ””โ”€โ”€ structs.h       # Common C++ structs (NetworkOutput, etc.)
โ”‚   โ”œโ”€โ”€ __init__.py         # Exposes public API (run_mcts, configs, etc.)
โ”‚   โ”œโ”€โ”€ config.py           # Python SearchConfiguration (Pydantic)
โ”‚   โ”œโ”€โ”€ mcts_wrapper.py     # Python network interface definition & run_mcts wrapper
โ”‚   โ””โ”€โ”€ py.typed            # Marker file for type checkers (PEP 561)
โ”œโ”€โ”€ tests/                  # Python tests ([tests/README.md](tests/README.md))
โ”‚   โ”œโ”€โ”€ conftest.py
โ”‚   โ””โ”€โ”€ test_alpha_wrapper.py # Tests for AlphaZero functionality
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ MANIFEST.in             # Specifies files for source distribution
โ”œโ”€โ”€ pyproject.toml          # Build system & package configuration
โ”œโ”€โ”€ README.md               # This file
โ””โ”€โ”€ setup.py                # Setup script for C++ extension building

๐Ÿ› ๏ธ Building from Source

  1. Clone the repository: git clone https://github.com/lguibr/trimcts.git
  2. Navigate to the directory: cd trimcts
  3. Recommended: Create and activate a virtual environment:
    python -m venv .venv
    source .venv/bin/activate # On Windows use `.venv\Scripts\activate`
    
  4. Install build dependencies: pip install pybind11>=2.10 cmake wheel
  5. Clean previous builds (important if switching Python versions or encountering issues):
    rm -rf build/ src/trimcts.egg-info/ dist/ src/trimcts/trimcts_cpp.*.so
    
  6. Install the package in editable mode: pip install -e .

๐Ÿงช Running Tests

# Make sure you have installed dev dependencies
pip install -e .[dev]
pytest

๐Ÿค Contributing

Contributions are welcome! Please follow standard fork-and-pull-request workflow. Ensure tests pass and code adheres to formatting/linting standards (Ruff, MyPy).

๐Ÿ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

trimcts-1.3.0-cp312-cp312-win_amd64.whl (183.0 kB view details)

Uploaded CPython 3.12Windows x86-64

trimcts-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

trimcts-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (218.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

trimcts-1.3.0-cp312-cp312-macosx_14_0_universal2.whl (90.3 kB view details)

Uploaded CPython 3.12macOS 14.0+ universal2 (ARM64, x86-64)

trimcts-1.3.0-cp311-cp311-win_amd64.whl (181.8 kB view details)

Uploaded CPython 3.11Windows x86-64

trimcts-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

trimcts-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (218.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

trimcts-1.3.0-cp311-cp311-macosx_14_0_universal2.whl (90.5 kB view details)

Uploaded CPython 3.11macOS 14.0+ universal2 (ARM64, x86-64)

trimcts-1.3.0-cp310-cp310-win_amd64.whl (179.1 kB view details)

Uploaded CPython 3.10Windows x86-64

trimcts-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

trimcts-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (218.6 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

trimcts-1.3.0-cp310-cp310-macosx_14_0_universal2.whl (89.2 kB view details)

Uploaded CPython 3.10macOS 14.0+ universal2 (ARM64, x86-64)

File details

Details for the file trimcts-1.3.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: trimcts-1.3.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 183.0 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for trimcts-1.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 69a3b4f3ce6b47865016125c8644fac010bb81f07fd4dc8a5a5158adc57436eb
MD5 1ee7d2a151f1201c0a01970f2745b314
BLAKE2b-256 bd87d0ed0c5b9b602460be2163ff603be7e5b23449c10f03cb2ad15e4739542d

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp312-cp312-win_amd64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c298929dc949c76425e104ac8b62126f52ebd4ed407dd6fc20dfb1bd20726efd
MD5 582ff7a64ec21e3b95b17fafe55e876a
BLAKE2b-256 7843b3bde20efe19bdb5ebfc0bfa65fdc1814d23420f30167d18b5cc1016b919

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b6215bfb848bf4ba351dc0934c6e1ab46af1f4ac3aaae8c9d085e4339afa98e2
MD5 634003e056ebe82083fab3d70cf62d83
BLAKE2b-256 c13872aecbe0086de3476ee7492eb215dd7edc2b7d0b46e8f36f9b59f2fa3209

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp312-cp312-macosx_14_0_universal2.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp312-cp312-macosx_14_0_universal2.whl
Algorithm Hash digest
SHA256 c616d503495436b71cd1c9eea03ae83c33f145d97e09fe586e531c59b5436086
MD5 e025587505b9ed7d2bb3d6d44122fe1f
BLAKE2b-256 27edf24c4f79aa0109bfcec85c1c9e48a4c96aae3289eae99880a80be4d3e9ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp312-cp312-macosx_14_0_universal2.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: trimcts-1.3.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 181.8 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for trimcts-1.3.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 60c914a149dea858be3bf971c1694b9a2be582b7a888147a2b0680e34aeed6e4
MD5 82d9726b56fa703967b5ffe90d4455a1
BLAKE2b-256 054f6585b2aea9767ffbb097888e32e178f2b0032fec969a5fe7f5a037957656

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp311-cp311-win_amd64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4733c95704754d4664a340682dfd66a13df1e0249b9ca53f7ed9c6fb4d88cc78
MD5 49639404b3003726117d8c596befb3a3
BLAKE2b-256 3788868e6e9142d9cec141dce305c8250fd508666e21013bd32487c121647503

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cb1e60e325ef94481125931c19f0c9bebf8d2bd6559d51f928f1a54cc6c6ce71
MD5 2127c3fba690846bc4058b6647a05a87
BLAKE2b-256 cbd4470f79e60333cb850fab50c860661163ef0c864a4a153eaa25dab7f823e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp311-cp311-macosx_14_0_universal2.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp311-cp311-macosx_14_0_universal2.whl
Algorithm Hash digest
SHA256 e3fb82d622ada04b920ea04199181f681f9e298334d72192af2caab9a851970d
MD5 f9ee54cd8b615f4e6ec17267a3218c8a
BLAKE2b-256 29a392acfefe019426c163117ca7ce02c03817cd08b21a015ca9708bcb614763

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp311-cp311-macosx_14_0_universal2.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: trimcts-1.3.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 179.1 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for trimcts-1.3.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 018c760011b489068a2d33b0c6f85df4c6866329bd7972b1b1d9c13366d171c7
MD5 d68ac24c47ced3006c821f038da48b1d
BLAKE2b-256 11307a6e8d89bd9bebd5a1aaadadc98e95914fe4ec53183f6cde32360e1115b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp310-cp310-win_amd64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8bd91db5b7bf04fb2ad1f992ff8961cad13be98d323ecc70a6b7496e9d875047
MD5 efd90862e8916a64f3e0343e01d1cc63
BLAKE2b-256 f5e6cec27d12fa5599e1d66615a46bd0ff677eeb5a026fe594d07f259f63705c

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4ed806c4ff39d6534bb4f4a6d0d8eade7f46cb96c950f3b2c0de2e211e826091
MD5 fdfd8c684f81658858568a0d3ef60022
BLAKE2b-256 3003ec83eb658ffa935bd177ee124b63eb5c28bd85b963ae13b84b0920eeb3b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trimcts-1.3.0-cp310-cp310-macosx_14_0_universal2.whl.

File metadata

File hashes

Hashes for trimcts-1.3.0-cp310-cp310-macosx_14_0_universal2.whl
Algorithm Hash digest
SHA256 63c24f34f1ca2ea5997ed9e5c6d57baaa02d96a33272e023f331f62d559364a5
MD5 751fe69b5daf5805e1a89da00e69ac26
BLAKE2b-256 7703126270fcd62be5c3066dbb841280b0224519233c11876032f676c24df94e

See more details on using hashes here.

Provenance

The following attestation bundles were made for trimcts-1.3.0-cp310-cp310-macosx_14_0_universal2.whl:

Publisher: ci_cd.yml on lguibr/trimcts

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page