봇 실행 헬퍼를 평가 모듈로 통합
This commit is contained in:
@@ -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,
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user