Skip to content

KapaSique/maze-crawler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧩 Maze Crawler β€” Kaggle Simulation Competition

Agent for Kaggle's Maze Crawler simulation competition. Two factories race northward through a scrolling maze. The game ends when the scroll boundary reaches your factory. Metric: ELO ladder rating (higher is better, starts ~600 and calibrates over hours of episodes).

The key insight: this is a survival race, not a combat game. Enemies are visible only ~3% of turns through fog-of-war; the real opponent is the scroll boundary itself.

Version Ladder Score Note
πŸ… v18 (peak stable) 1046.6 (#70) Pure BFS sprinter, no extras
πŸš€ v21 (current) ~1017–1057 Mine economy + ceiling buffer
v15 932.4 First jump-BFS (ported from public LB1223 notebook)
v10 513.8 Survival-first heuristic (first real improvement over v9)
v9 492.1 Original baseline

Status: ladder fluctuates Β±50 points per session. Best observed: 1057.5, rank #53/459 (top 12%). All versions above v15 use the same jump-BFS core; improvements are marginal tuning.


Core Strategy

The winning approach is pure north-sprinting via jump-preferred BFS, ported and tuned from the public notebook "Top 2 Maze Crawler β€” Jump-Preferred BFS (LB 1223)" by Nicolas Bridelance.

Factory spawns 1 scout β†’ scout runs BFS toward (factory_row + target_ahead)
               JUMP when cooldown == 0 AND jump clears >1 row
               WALK otherwise on shortest path
Factory itself flees north: JUMP_NORTH on emergency (gap ≀ 2), step otherwise

Critical engine detail most agents miss: cooldowns tick BEFORE action processing, so a robot with observed cd == 1 can act this turn. Planning only at cd == 0 wastes every other move window. This alone accounts for a large chunk of the jump-BFS advantage over naive agents.


Engineering Journey

Why self-play is a trap

Agents v10–v14 were tuned via local self-play (one frozen opponent). Every iteration that looked like +10% local winrate turned out to be noise (Β±8% at 30–50 seeds). The real ladder settled all of them within Β±50 ELO of each other.

Lesson: mirror self-play saturates at 50% Β± noise. Only the calibrated ladder matters. This is especially painful because ladder calibration takes hours of episodes.

The v15 turning point

Reading the public LB1223 notebook revealed the cooldown bug and the jump-BFS structure. v15 jumped from ~500 to 932 ELO overnight β€” a bigger gain than the entire v9β†’v14 iteration.

This is the Mahog principle applied to simulation: reading the top public code first beats weeks of local tuning.

v16–v21: diminishing returns

Every "improvement" after v15 (mine economy, scouts, ceiling buffer, worker logic) either held at ~1000 or degraded. v18 β€” a clean, minimal sprinter β€” held at 1046.6. v19 added a miner pipeline and collapsed to 659 ELO. Classic complexity trap.

The agent that wins is the simplest one that correctly implements the core mechanic.


Version History

Version Ladder Score Change
v9 492 original heuristic (over-builds, bankrupt deaths)
v10 514 survival-first, energy solvency, scout1 build order
v11 471 BFS escape + factory feeding β€” regressed
v12 606 tuned margins
v13 737 tuned scoring weights
v15 932 jump-BFS from public LB1223 β€” step change
v16 864 over-tuned, regressed
v18 1047 pure sprinter, minimal β€” BEST STABLE
v19 659 miner pipeline β€” catastrophic regression
v20 980 scouts + ceiling buffer
v21 ~1020 mine economy + ceiling buffer (current)

Repo Structure

agents/
  baseline_v9.py … baseline_v22.py   agent version history
  cand_v23*.py                        experimental candidates
  ext_jumpbfs_lb1223.py               reference: public LB1223 notebook port
  starter_baseline.py                 Kaggle starter kit (preserved)
scripts/
  arena.py           local self-play tournament harness
  tournament.py      multi-agent round-robin
  analyze_ladder.py  parse ladder JSON β†’ ELO trends
  breakdown.py       per-version death cause analysis
  survival.py        factory survival rate by version
  compare_death.py   death cause diff between two agents
maze_submit/
  build_submission.py   packages main.py for Kaggle kernel submit
main.py                 current submission (single self-contained file)
tests/
  test_agent_smoke.py   smoke test: synthetic obs + env episode
SOLUTION.md             full architecture and iteration notes

Local Setup

python3.12 -m venv .venv-sim
source .venv-sim/bin/activate
pip install kaggle-environments

# Run smoke tests
python -m unittest discover tests

# Self-play tournament (30 seeds, v21 vs v18)
python scripts/arena.py --agent agents/baseline_v21.py \
                         --opponent agents/baseline_v18.py \
                         --seeds 30

Note: local winrate is a noisy proxy for ladder performance. Use it only to catch regressions (crashes, obvious death spikes). The real signal is the Kaggle ladder after ~1h of episodes.

About

🧩 Kaggle Maze Crawler β€” simulation agent. Jump-BFS pure sprinter, ELO 1057 (#53/459, top ~12%).

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages