봇 실행 헬퍼를 평가 모듈로 통합

This commit is contained in:
2026-05-06 20:45:14 +09:00
parent 407d592f5e
commit 1843d93df2
4 changed files with 3 additions and 70 deletions
@@ -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",
]
@@ -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",
]
@@ -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,
}
+3 -2
View File
@@ -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: