diff --git a/src/coolrl_lost_cities/games/classic/__init__.py b/src/coolrl_lost_cities/games/classic/__init__.py index 1efc0e3..32227dc 100644 --- a/src/coolrl_lost_cities/games/classic/__init__.py +++ b/src/coolrl_lost_cities/games/classic/__init__.py @@ -4,8 +4,6 @@ from .bots import ( LostCitiesBot, available_bot_names, build_bot, - play_game, - run_series, ) from .env import LostCitiesEnv from .evaluation import ( @@ -38,10 +36,8 @@ __all__ = [ "classic_config", "evaluate_bot", "make_bot_factory", - "play_game", "play_game_for_evaluation", "play_match", - "run_series", ] diff --git a/src/coolrl_lost_cities/games/classic/bots/__init__.py b/src/coolrl_lost_cities/games/classic/bots/__init__.py index 8d4d901..c497f92 100644 --- a/src/coolrl_lost_cities/games/classic/bots/__init__.py +++ b/src/coolrl_lost_cities/games/classic/bots/__init__.py @@ -3,7 +3,6 @@ from __future__ import annotations from ..interfaces import BotInput, LostCitiesBot from .heuristic import SafeHeuristicBot from .passive import PassiveDiscardBot -from .play import play_game, run_series from .random import RandomBot from .registry import DEFAULT_BOT, available_bot_names, build_bot @@ -16,6 +15,4 @@ __all__ = [ "SafeHeuristicBot", "available_bot_names", "build_bot", - "play_game", - "run_series", ] diff --git a/src/coolrl_lost_cities/games/classic/bots/play.py b/src/coolrl_lost_cities/games/classic/bots/play.py deleted file mode 100644 index 29dcda6..0000000 --- a/src/coolrl_lost_cities/games/classic/bots/play.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import annotations - -from dataclasses import replace - -from ..game import GameState, LostCitiesConfig -from ..interfaces import LostCitiesBot - -try: - import numpy as np -except ImportError as exc: # pragma: no cover - raise RuntimeError("numpy is required for Lost Cities bots") from exc - - -def play_game( - bot0: LostCitiesBot, - bot1: LostCitiesBot, - config: LostCitiesConfig, - *, - seed: int | None = None, - max_steps: int = 10_000, -) -> GameState: - game_config = replace(config, seed=seed) if seed is not None else config - state = GameState.new_game(game_config) - bots = [bot0, bot1] - for _ in range(max_steps): - if state.terminal: - return state - action = bots[state.current_player].act(state) - state.apply_action(action) - raise RuntimeError(f"game exceeded max_steps={max_steps}") - - -def run_series( - bot0: LostCitiesBot, - bot1: LostCitiesBot, - config: LostCitiesConfig, - *, - games: int = 100, - seed: int = 0, -) -> dict: - diffs: list[int] = [] - wins0 = 0 - wins1 = 0 - draws = 0 - for index in range(games): - state = play_game(bot0, bot1, config, seed=seed + index) - diff = state.score_diff(0) - diffs.append(diff) - if diff > 0: - wins0 += 1 - elif diff < 0: - wins1 += 1 - else: - draws += 1 - return { - "games": games, - "avg_diff": float(np.mean(diffs)) if diffs else 0.0, - "wins0": wins0, - "wins1": wins1, - "draws": draws, - } diff --git a/tests/games/classic/test_bots.py b/tests/games/classic/test_bots.py index 17634de..735f5b2 100644 --- a/tests/games/classic/test_bots.py +++ b/tests/games/classic/test_bots.py @@ -4,9 +4,9 @@ from coolrl_lost_cities.games.classic.bots import ( LostCitiesBot, RandomBot, SafeHeuristicBot, - play_game, ) from coolrl_lost_cities.games.classic.bots.heuristic import draw_from_discard_action +from coolrl_lost_cities.games.classic.evaluation import play_game_for_evaluation def test_builtin_bots_implement_lost_cities_bot() -> None: @@ -15,7 +15,7 @@ def test_builtin_bots_implement_lost_cities_bot() -> None: def test_safe_heuristic_mirror_match_finishes() -> None: - state = play_game( + state, result = play_game_for_evaluation( SafeHeuristicBot(), SafeHeuristicBot(), LostCitiesConfig(n_colors=3, n_ranks=5, n_handshakes=1, hand_size=5), @@ -23,6 +23,7 @@ def test_safe_heuristic_mirror_match_finishes() -> None: max_steps=200, ) assert state.terminal is True + assert result.timed_out is False def test_safe_heuristic_opponent_value_ignores_hidden_hand() -> None: