|
| 1 | +# Porting a Gomoku bot to the CodeClash `get_move` contract |
| 2 | + |
| 3 | +You are porting ONE open-source Gomoku / Gobang / Renju bot into a single self-contained |
| 4 | +`main.py` that defines **one function**: |
| 5 | + |
| 6 | +```python |
| 7 | +def get_move(board, color) -> tuple: # returns (row, col) |
| 8 | +``` |
| 9 | + |
| 10 | +- `board`: a 15x15 list-of-lists of ints — `0`=empty, `1`=black, `2`=white. |
| 11 | +- `color`: `"black"` or `"white"`. Black moves first. Win = 5 in a row (H/V/either diagonal). |
| 12 | +- Return `(row, col)` of an **empty** cell (0-indexed). Returning an occupied/off-board cell or |
| 13 | + raising an exception forfeits the game, so be defensive. |
| 14 | + |
| 15 | +A clean, dependency-free reference implementation lives at |
| 16 | +`scripts/ladder/examples/main.py` — read it first; mirror its structure and defensive style. |
| 17 | + |
| 18 | +## Hard rules |
| 19 | +- **Stdlib only.** No numpy/pygame/tkinter/torch/etc. The arena image is plain Python 3.10 with |
| 20 | + the standard library only. Re-express any array math in pure Python lists. |
| 21 | +- **No trained weights / no NN.** If the source bot is AlphaZero/CNN/RL and has no rule-based |
| 22 | + fallback, DO NOT port it — say so in your report (it should have been filtered out already). |
| 23 | +- **One file, one function.** Everything the bot needs (search, evaluation, tables) goes inside |
| 24 | + `main.py`. Helper functions/classes are fine; `get_move` is the entry point. |
| 25 | +- **Never raise.** Wrap the body so any internal error falls back to a safe legal move (e.g. the |
| 26 | + first empty cell, or center). A crash = a forfeit. |
| 27 | +- **Be reasonably fast.** There is no hard per-move timeout in the engine, but a game plays many |
| 28 | + moves and the round-robin plays many games — keep search depth/rollouts modest (a move should |
| 29 | + return in well under a second on a 15x15 board). Cap minimax depth / MCTS iterations sensibly. |
| 30 | + |
| 31 | +## What to extract from the source |
| 32 | +Most source repos wrap their AI in a GUI (pygame/tkinter), a Gomocup/piskvork stdin-stdout |
| 33 | +protocol loop, or a class with its own board representation. Ignore all of that. Find the core |
| 34 | +**"given a board, choose a move"** logic — usually a `minimax`/`negamax`/`alphabeta`, an MCTS |
| 35 | +tree search, or a threat/shape evaluation over candidate cells — and re-express it as: |
| 36 | + |
| 37 | +1. Convert the arena `board` (list-of-lists, 0/1/2) to whatever the algorithm wants (often the |
| 38 | + same, sometimes it uses -1/1 or 'X'/'O' — remap). Determine `me`/`opp` from `color`. |
| 39 | +2. Run the source's move-selection over the current board. |
| 40 | +3. Map the chosen move back to a `(row, col)` int tuple and return it. |
| 41 | + |
| 42 | +Keep behavior faithful: same evaluation weights, same search depth, same tie-breaks where you can. |
| 43 | +If the source relies on state across turns (opening books, transposition tables, incremental |
| 44 | +board), either recompute from `board` each call or hold it in module-level globals keyed sensibly |
| 45 | +— but the engine calls `get_move` fresh each turn with the full board, so stateless recomputation |
| 46 | +is usually simplest and correct. |
| 47 | + |
| 48 | +## For non-Python sources (JS / Java / C++ — the "PROTOCOL-PORT" bucket) |
| 49 | +Reimplement the evaluation + search in Python. Prioritize faithfulness of the **evaluation |
| 50 | +function** (shape/threat scoring tables) and the **search** (depth, pruning); these determine |
| 51 | +strength. Drop language-specific perf tricks (bitboards, Zobrist/TT) unless easy — correctness and |
| 52 | +the eval shape matter more than raw speed for the ladder. |
| 53 | + |
| 54 | +## Deliverable |
| 55 | +Write your port to `scripts/ladder/ports/<name>.py` (see the batch prompt for the exact filename, |
| 56 | +e.g. `colingogogo.py`). It must: |
| 57 | +- `python3 -c "import ast; ast.parse(open(FILE).read())"` cleanly, |
| 58 | +- define a top-level `get_move(board, color)`, |
| 59 | +- return a legal `(row, col)` on an empty starter board and mid-game, never raising. |
| 60 | + |
| 61 | +Keep a short module docstring naming the source (repo + author + algorithm) and noting any |
| 62 | +simplifications/dropped features (e.g. "dropped Zobrist TT", "MCTS iters capped at 2000"). |
0 commit comments