Ahead-of-time C++ engine scaffold for Kaggle's Maze Crawler competition.
The goal of this repository is to keep the Python submission layer thin and move the expensive work into a deterministic C++ engine exposed through pybind11. The current implementation is a working scaffold: it builds, imports from Python, runs rule-focused smoke tests, and contains the fixed-buffer state layout needed for later search tuning.
src/crawler_engine.hppdefines the fixed-size state model:- absolute global grid arrays:
20 * 512cells for walls, crystals, mines, nodes, and belief fields. - active 20x20 tactical bitboards backed by
uint64_t[7]. - robot Structure of Arrays storage with fixed capacity and UID slots.
- absolute global grid arrays:
src/crawler_engine.cppimplements:- deterministic turn stepping in the official rules order.
- spawn-before-combat behavior, crush hierarchy, friendly fire, crystal/mine phases, scrolling, and boundary cleanup.
- belief-state update, enemy probability diffusion, optimistic hidden-row determinization, and conservative macro/action scaffolding.
src/bindings.cppexposes the engine as a Python module namedcrawler_engine.main.pyis the Kaggle entrypoint. It maintains one C++ engine per player and returns{uid: "PRIMITIVE_ACTION"}.submission.pyis a local alias formain.agent.test.pycontains bridge and core rule smoke tests.
The system Python in many dev containers is externally managed, so a virtual environment is recommended.
python3 -m venv /tmp/maze-crawler-venv
/tmp/maze-crawler-venv/bin/python -m pip install -r requirements-dev.txtDependencies:
pybind11numpypytestkaggle-environments
Configure CMake with the same Python interpreter that has pybind11 installed:
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DPython3_EXECUTABLE=/tmp/maze-crawler-venv/bin/python
cmake --build build -jRelease builds use C++20 and, for GCC/Clang, -O3 -march=native -ffast-math.
The compiled extension is written under build/, for example:
build/crawler_engine.cpython-313-x86_64-linux-gnu.so
Run the smoke script:
PYTHONPATH=build /tmp/maze-crawler-venv/bin/python test.pyRun the pytest form:
PYTHONPATH=build /tmp/maze-crawler-venv/bin/python -m pytest -q test.pyCurrent smoke coverage includes:
- Python bridge import and action generation.
- Factory build/spawn behavior.
- Same-type annihilation.
- Stronger-type crush resolution.
- Crystal collection and combat consumption.
- Transfer cap behavior.
- Off-board jump destruction.
import crawler_engine
engine = crawler_engine.Engine(player=0)
engine.update_observation(
player,
walls, # flat length-400 sequence, -1 for unknown
crystals, # {"col,row": energy}
robots, # {"uid": [type, col, row, energy, owner, move_cd, jump_cd, build_cd]}
mines, # {"col,row": [energy, maxEnergy, owner]}
mining_nodes, # {"col,row": 1}
southBound,
northBound,
step,
)
actions = engine.choose_actions(time_budget_ms=2000, seed=123)actions is a Kaggle-compatible dictionary:
{"0-0": "BUILD_WORKER", "3-4": "NORTH"}The bound API also exposes:
engine.step(actions)engine.determinize(seed=0)engine.debug_state()
main.py defines:
def agent(obs, config):
...For local use with the compiled extension:
PYTHONPATH=build /tmp/maze-crawler-venv/bin/python - <<'PY'
from types import SimpleNamespace
from main import agent
obs = SimpleNamespace(
player=0,
walls=[0] * 400,
crystals={},
robots={"f0": [0, 5, 2, 1000, 0, 0, 0, 0]},
mines={},
miningNodes={},
southBound=0,
northBound=19,
step=0,
)
config = SimpleNamespace(width=20, workerCost=200, wallRemoveCost=100)
print(agent(obs, config))
PYIf crawler_engine cannot be imported, main.py falls back to a simple Python policy so import failures are visible without crashing immediately.
- Hot simulation state is fixed-capacity.
CrawlerSim::step()uses fixed scratch arrays and avoids heap allocation. - Board truth and belief use absolute row indexing to avoid repeated active-window coordinate arithmetic in longer rollouts.
- Active-window bitboards are rebuilt for tactical masks and iterate with C++20 bit operations.
- Enemy belief update explicitly clears probability from visible empty cells, then diffuses hidden probability by unit speed and known walls.
- Hidden future rows are sampled with optimistic east/west symmetry and center-door priors rather than random wall noise.
This is a scaffold, not a finished leaderboard bot. The deterministic engine and bridge are in place, but the Macro-ISMCTS layer currently uses conservative fixed-buffer placeholders and heuristic fallback actions. The next major work item is validating simulator parity against the official environment on a larger set of generated edge cases, then replacing the placeholder search policy with tuned rollouts and macro priors.