Skip to content
8 changes: 6 additions & 2 deletions codeclash/arenas/robocode/robocode.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@

class RoboCodeArena(CodeArena):
name: str = "RoboCode"
description: str = f"""Robocode (Tank Royale) is a programming game where your code is the tank: each turn your bot sends intents—speed plus body/gun/radar turn rates and firepower—based on the game state it perceives via radar.
Your program decides how to move, aim, and fire in a deterministic, turn-based arena to outlast other bots.
description: str = f"""Robocode is a programming game where your code IS the tank. This is classic
Robocode (the `robocode.*` API compiled against robocode.jar) — NOT Robocode Tank Royale.
Your bot is a Java class that `extends robocode.Robot` (or `robocode.AdvancedRobot` for non-blocking
control): its `run()` method drives the tank in a loop (e.g. `ahead(100)`, `turnGunRight(90)`,
`fire(3)`), and it reacts to events like `onScannedRobot(ScannedRobotEvent)`, `onHitByBullet(...)`,
and `onHitWall(...)`. Move, aim the gun, sweep the radar, and fire to outlast other bots.
Your bot logic must be written in Java and located in the `robots/custom/` directory.
Keep the main bot class named `{str(RC_FILE)}`, but you can include additional Java files if you'd like."""
default_args: dict = {
Expand Down
15 changes: 12 additions & 3 deletions codeclash/tournaments/ladder.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
logger = get_logger("ladder")


def _player_slug(branch_init: str) -> str:
"""
Turn a ``human/<author>/<bot>`` init branch into a bare, filesystem-safe player name:
strip the ``human/`` prefix and join the rest with ``__`` (e.g. ``human/aleksiy325/snek-two``
-> ``aleksiy325__snek-two``).
"""
return branch_init.replace("human/", "").replace("/", "__")


def resolve_ladder_rules(ladder_rules: dict, rounds: int) -> tuple[int, int]:
"""Validate the required ``ladder_rules`` block and return ``(min_round_wins, win_last_k)``.

Expand Down Expand Up @@ -88,9 +97,9 @@ def build_ladder(config: dict, workers: int = 1) -> None:
for i in range(num_players):
for j in range(i + 1, num_players):
player1 = copy.deepcopy(players[i])
player1["name"] = player1["branch_init"]
player1["name"] = _player_slug(player1["branch_init"])
player2 = copy.deepcopy(players[j])
player2["name"] = player2["branch_init"]
player2["name"] = _player_slug(player2["branch_init"])
pvp_config = {**copy.deepcopy(config), "players": [player1, player2]}
vs = f"PvpTournament.{player1['name']}_vs_{player2['name']}".replace("/", "_")
output_dir = LOCAL_LOG_DIR / "ladder" / config["game"]["name"] / vs
Expand Down Expand Up @@ -199,7 +208,7 @@ def run(self) -> dict:
opponent_rank = 0
for idx, opponent in enumerate(self.ladder):
opponent_rank = len(self.ladder) - idx
opponent["name"] = opponent["branch_init"].replace("human/", "").replace("/", "_")
opponent["name"] = _player_slug(opponent["branch_init"])
if "branch_init" in self.player and idx > 0:
# After first opponent, remove branch_init so the player continues from the
# previous tournament's codebase.
Expand Down
14 changes: 14 additions & 0 deletions configs/ladder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ open-source Gomoku/Gobang AIs ported into the arena's single-file `get_move(boar
lihongxun945, blackstone, blupig) reimplemented in stdlib Python — alongside a strategic starter.
AlphaZero/CNN bots were skipped (need trained weights).

### RoboCode (newly added)

The [CC:RoboCode](https://github.com/CodeClash-ai/RoboCode) repo hosts 116 human bots on `human/robocode/*`
branches (bot code lives only on the branches, not in this repo). This arena is **classic Robocode**
(`robocode.*` API compiled against `robocode.jar`), so importing open-source bots is mostly a
mechanical copy-in + rename rather than a strategy rewrite: each bot's Java class(es) are placed in
`robots/custom/`, the main class renamed to `MyTank`, `package custom;`. The set spans the shipped
sample bots (SittingDuck/Walls/Corners/…) through famous RoboWiki/PEZ micro-mini bots (Aristocles,
Pugilist, HawkOnFire) up to a single-file **DrussGT** (a world-class bot) as the top rung; a few use
Robocode's sanctioned `getDataFile` persistence (degrades gracefully without cross-battle saves).
Diamond/BeepBoop remain as future top rungs (nested-package multi-file → need flattening). Each import
was verified to **compile and play a real battle**; every bot's source repo/author/license is recorded
as a header comment in its branch files.

## Config layout

Each arena has a few kinds of config in this folder:
Expand Down
258 changes: 258 additions & 0 deletions configs/ladder/make_robocode.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
# Round-robin over the human classic-Robocode bots (imported from ~30 open-source repos; each bot's
# origin URL/author/license is recorded as a header comment in its human/* branch files), used to
# RANK them via Elo/Bradley-Terry -> see robocode.yaml. rounds:0 = dummy players play baseline
# battles (no code edits). N bots -> N*(N-1)/2 pairs; each pair plays sims_per_round rounds (batched
# 10 at a time, sim_concurrency parallel). Bots live on CodeClash-ai/RoboCode human/* branches; Docker required.
# COST (measured on an 8-core box: a pair is ~11.8s fixed overhead + ~9.7s per 100 sims, so at
# sims_per_round=300 a single pair is ~41s solo and ~25s/pair of throughput under --workers 6).
# 116 bots -> 6670 pairs -> ~46 core-hours -> ~2 days on an 8-core box (-w 6). Resumable: skips
# already-logged pairs, so a killed run can be re-launched. Scale --workers with cores (~cores-2).
# Run: uv run codeclash ladder make configs/ladder/make_robocode.yaml --workers 6
tournament:
rounds: 0
game:
name: RoboCode
sims_per_round: 300
sim_concurrency: 5
# Ranking only needs per-battle scores (results_*.txt), not replays. Recording every sim writes
# ~8.7MB of compressed replay XML per pair (~59GB over 6670 pairs) and pins a gzip core on every
# log copy, so disable it here.
record_ratio: 0
args:
nodisplay: true
nosound: true
players:
- agent: dummy
branch_init: human/kinnla/antiwalls
- agent: dummy
branch_init: human/pez/aristocles
- agent: dummy
branch_init: human/vftheodoro/barbiescript
- agent: dummy
branch_init: human/johan_adriaans/berendbotje
- agent: dummy
branch_init: human/pez/blackwidow
- agent: dummy
branch_init: human/pez/blackwidow_mini
- agent: dummy
branch_init: human/winstliu/bobthebuilder
- agent: dummy
branch_init: human/lucasgch/bt7274
- agent: dummy
branch_init: human/namnguyenthanhwork/cham
- agent: dummy
branch_init: human/looklazy/chilibot
- agent: dummy
branch_init: human/pez/chironex_micro
- agent: dummy
branch_init: human/pez/chironex_mini
- agent: dummy
branch_init: human/robo_code/corners
- agent: dummy
branch_init: human/txeverson/crawler
- agent: dummy
branch_init: human/robo_code/crazy
- agent: dummy
branch_init: human/philipmjohnson/dacruzer
- agent: dummy
branch_init: human/trex22/deepthought
- agent: dummy
branch_init: human/pseminatore/dodgebot_jnk
- agent: dummy
branch_init: human/logancsc/dodgebot2
- agent: dummy
branch_init: human/vikdov/dominatorx
- agent: dummy
branch_init: human/pez/droidpoet
- agent: dummy
branch_init: human/admiralrasmussen/drussgt
- agent: dummy
branch_init: human/andrekorol/exterminador
- agent: dummy
branch_init: human/robo_code/fire
- agent: dummy
branch_init: human/pez/frankie
- agent: dummy
branch_init: human/linuxuser0/genetic
- agent: dummy
branch_init: human/pez/gf1
- agent: dummy
branch_init: human/josephjeon/gntest
- agent: dummy
branch_init: human/pez/gouldingi
- agent: dummy
branch_init: human/kylebennett/gruffalo
- agent: dummy
branch_init: human/pez/haikupoet
- agent: dummy
branch_init: human/pez/haikuwalls
- agent: dummy
branch_init: human/admiralrasmussen/hawkonfire
- agent: dummy
branch_init: human/zhiwei121/hero_pm
- agent: dummy
branch_init: human/kylebennett/hugbot
- agent: dummy
branch_init: human/mcd8604/hunter
- agent: dummy
branch_init: human/pez/hypoleach
- agent: dummy
branch_init: human/alpian/ianstank
- agent: dummy
branch_init: human/pez/icarus
- agent: dummy
branch_init: human/wouterjoosse/infinitylock
- agent: dummy
branch_init: human/it_economics/ite_bomax
- agent: dummy
branch_init: human/it_economics/ite_claptrap
- agent: dummy
branch_init: human/it_economics/ite_cliffbot2
- agent: dummy
branch_init: human/it_economics/ite_ctbot
- agent: dummy
branch_init: human/it_economics/ite_florian2
- agent: dummy
branch_init: human/it_economics/ite_m9
- agent: dummy
branch_init: human/it_economics/ite_simple
- agent: dummy
branch_init: human/it_economics/ite_terminator
- agent: dummy
branch_init: human/joaomcarvalho/jeujdapeu
- agent: dummy
branch_init: human/dankraemer/juggernaut
- agent: dummy
branch_init: human/u_0x65_e/kokomo
- agent: dummy
branch_init: human/pez/leach
- agent: dummy
branch_init: human/pez/leachpmc
- agent: dummy
branch_init: human/pez/littlebrother
- agent: dummy
branch_init: human/pez/littleevilbrother
- agent: dummy
branch_init: human/pez/mako
- agent: dummy
branch_init: human/tibola/markiv
- agent: dummy
branch_init: human/zcjerry229/markrobo
- agent: dummy
branch_init: human/pez/marshmallow
- agent: dummy
branch_init: human/mgalushka/maximbot
- agent: dummy
branch_init: human/gjgomez/mb2
- agent: dummy
branch_init: human/denssle/megaborsten
- agent: dummy
branch_init: human/team488/meow
- agent: dummy
branch_init: human/andrekorol/myfirstkiller
- agent: dummy
branch_init: human/robo_code/myfirstrobot
- agent: dummy
branch_init: human/luke_f_w/nagisphere
- agent: dummy
branch_init: human/andr3eee1/npcomplete
- agent: dummy
branch_init: human/iagomonteiro13579/npcsniper
- agent: dummy
branch_init: human/andrekorol/oppswantmedead
- agent: dummy
branch_init: human/pez/paolo
- agent: dummy
branch_init: human/kcanida/pikachu
- agent: dummy
branch_init: human/pez/poet
- agent: dummy
branch_init: human/pmontp19/propiavancat
- agent: dummy
branch_init: human/pez/pugilist
- agent: dummy
branch_init: human/gabriel_lw/quadwall
- agent: dummy
branch_init: human/robo_code/ramfire
- agent: dummy
branch_init: human/robo_code/regullarmonk
- agent: dummy
branch_init: human/g_otn/reimu
- agent: dummy
branch_init: human/sacdalance/robrrrat
- agent: dummy
branch_init: human/miradoconsulting/roleksii
- agent: dummy
branch_init: human/avsthiago/sadbot
- agent: dummy
branch_init: human/alexbay218/shreker
- agent: dummy
branch_init: human/robo_code/sittingduck
- agent: dummy
branch_init: human/pez/smallpoet
- agent: dummy
branch_init: human/robo_code/spinbot
- agent: dummy
branch_init: human/jonharder/starterbot
- agent: dummy
branch_init: human/mgalushka/supercorners
- agent: dummy
branch_init: human/mgalushka/supercrazy
- agent: dummy
branch_init: human/mgalushka/supermercutio
- agent: dummy
branch_init: human/mgalushka/superramfire
- agent: dummy
branch_init: human/mgalushka/superspinbot
- agent: dummy
branch_init: human/mgalushka/supertracker
- agent: dummy
branch_init: human/mgalushka/superwalls
- agent: dummy
branch_init: human/pez/swiffer
- agent: dummy
branch_init: human/tannerrogalsky/tannerbot1
- agent: dummy
branch_init: human/alpian/tarektank
- agent: dummy
branch_init: human/technischeinformatica/tearsofsteel
- agent: dummy
branch_init: human/pranav_prakash/thecarver
- agent: dummy
branch_init: human/barriosnahuel/tirolio
- agent: dummy
branch_init: human/pez/tityus
- agent: dummy
branch_init: human/robo_code/tracker
- agent: dummy
branch_init: human/robo_code/trackfire
- agent: dummy
branch_init: human/muzardo/trianglehunter
- agent: dummy
branch_init: human/rafaeljdesa/ultron
- agent: dummy
branch_init: human/ur4n0_235/ur4no
- agent: dummy
branch_init: human/robo_code/velocirobot
- agent: dummy
branch_init: human/john_paul_r/vergere
- agent: dummy
branch_init: human/pez/vertileach
- agent: dummy
branch_init: human/pez/vertimicro
- agent: dummy
branch_init: human/robo_code/walls
- agent: dummy
branch_init: human/pez/wallspoet
- agent: dummy
branch_init: human/pez/wallspoetas
- agent: dummy
branch_init: human/pez/wallspoethaiku
- agent: dummy
branch_init: human/admiralrasmussen/wavesurfing
- agent: dummy
branch_init: human/alexjamesmacpherson/wilde
- agent: dummy
branch_init: human/joaocarpim/wrecker
prompts:
game_description: RoboCode ladder
Loading