Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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