-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathladder.py
More file actions
78 lines (65 loc) · 2.93 KB
/
Copy pathladder.py
File metadata and controls
78 lines (65 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""`codeclash ladder` subcommands: build a ladder (make) and climb it (run).
Thin CLI adapter over :mod:`codeclash.tournaments.ladder`, which holds all ladder logic.
"""
from pathlib import Path
import typer
import yaml
from codeclash import CONFIG_DIR
from codeclash.tournaments.ladder import LadderTournament, build_ladder, resolve_ladder_rules # noqa: F401
from codeclash.utils.yaml_utils import resolve_includes
ladder_app = typer.Typer(
no_args_is_help=True,
add_completion=False,
rich_markup_mode="rich", # enables the [dim] markup used in the Examples blocks
context_settings={"help_option_names": ["-h", "--help"]},
)
def _load_config(config_path: Path) -> dict:
yaml_content = config_path.read_text()
preprocessed_yaml = resolve_includes(yaml_content, base_dir=CONFIG_DIR)
return yaml.safe_load(preprocessed_yaml)
@ladder_app.command("make")
def make(
config_path: Path = typer.Argument(..., help="Path to the ladder (round-robin) config file."),
workers: int = typer.Option(
1, "--workers", "-w", help="Pairwise tournaments to run concurrently (each pair is independent)."
),
):
"""Build a ladder: run PvP tournaments across all pairs of players (for ranking).
[dim]• codeclash ladder make configs/ladder/make_battlesnake.yaml[/dim]
"""
build_ladder(_load_config(config_path), workers=workers)
@ladder_app.command("run")
def run(
config_path: Path = typer.Argument(..., help="Path to the ladder config (with `player` + `ladder`)."),
cleanup: bool = typer.Option(False, "--cleanup", "-c", help="Clean up the game environment after running."),
output_dir: Path | None = typer.Option(None, "--output-dir", "-o", help="Output directory (default: logs/<user>)."),
suffix: str = typer.Option("", "--suffix", "-s", help="Suffix for the output folder name (no leading dot)."),
keep_containers: bool = typer.Option(
False, "--keep-containers", "-k", help="Do not remove containers after games/agent finish."
),
resume_from: Path | None = typer.Option(
None,
"--resume",
"-r",
help="Resume an interrupted run: pass its log dir. Skips cleared rungs and seeds from the "
"last cleared rung's pushed codebase. Requires push: True and the same config.",
),
):
"""Send a model up a ranked ladder, rung by rung, until it loses.
[dim]• codeclash ladder run path/to/ladder_config.yaml -c # clean up after each rung[/dim]
[dim]• codeclash ladder run path/to/ladder_config.yaml -r logs/<user>/LadderTournament... # resume[/dim]
"""
config = _load_config(config_path)
try:
tournament = LadderTournament(
config,
output_dir=output_dir,
suffix=suffix,
cleanup=cleanup,
keep_containers=keep_containers,
resume_from=resume_from,
)
except ValueError as e:
typer.echo(str(e))
raise typer.Exit(1)
tournament.run()