feat: add gameplay stats and restore Zenith rollout depth
Build and Push Docker Container / build-and-push (push) Successful in 3m6s
Build and Push Docker Container / build-and-push (push) Successful in 3m6s
- Add read-only gameplay statistics with filters and opponent comparisons. - Report move-trace latency percentiles and external timeout counts. - Pair engine latency with the preceding turn to separate timing stages. - Adjust Zenith rollout deepening for its larger timeout reserve. - Bump Zenith to 1.2.0 and document the fix and snake-stats command. - Cover statistics, trace aggregation, rollout depth, and verdict budgets.
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ SNAKE_REGISTRATIONS = {
|
||||
"snakes.strategies.prism", "1.5.0"
|
||||
),
|
||||
"ZenithBattleSnake_ClaudeOpus5_5": SnakeRegistration(
|
||||
"snakes.strategies.zenith", "1.1.0"
|
||||
"snakes.strategies.zenith", "1.2.0"
|
||||
),
|
||||
"DummSnake": SnakeRegistration("snakes.legacy.DummSnake", "1.0.0"),
|
||||
"LogicSnake": SnakeRegistration("snakes.legacy.LogicSnake", "1.1.0"),
|
||||
|
||||
@@ -4,6 +4,10 @@ from time import perf_counter
|
||||
from snakes.engine.survival_search import CompactSurvivalSearch
|
||||
|
||||
class BitboardSurvivalMixin:
|
||||
# Remaining budget above which rollouts against at most two enemies may look
|
||||
# one turn deeper. Snakes with a larger timeout reserve lower this threshold.
|
||||
_rollout_deepen_ms = 250.0
|
||||
|
||||
def _future_rollout_bonus(
|
||||
self, move: str, safe_moves: dict, my_body: list, other_snakes: list,
|
||||
food_set: set, is_constrictor: bool, width: int, height: int,
|
||||
@@ -36,7 +40,7 @@ class BitboardSurvivalMixin:
|
||||
depth = min(self._planning_depth, 2 if len(other_snakes) > 1 else 3)
|
||||
if remaining < 90:
|
||||
depth = min(depth, 2)
|
||||
elif remaining > 250 and len(other_snakes) <= 2:
|
||||
elif remaining > self._rollout_deepen_ms and len(other_snakes) <= 2:
|
||||
depth = min(4, depth + 1)
|
||||
raw = self._survival_search_context.search_selected(
|
||||
my_body=my_body,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""ZenithBattleSnake_ClaudeOpus5_5 v1.1.0
|
||||
"""ZenithBattleSnake_ClaudeOpus5_5 v1.2.0
|
||||
|
||||
Built on PrismBattleSnake_GPT_5_6_Sol v1.5.0. Prism's bitboard engine, duel
|
||||
search, and adversarial rollouts are inherited unchanged.
|
||||
@@ -15,6 +15,11 @@ Z2: Proven-loss veto — a candidate whose completed search proves a loss is
|
||||
replaced by the best non-losing candidate.
|
||||
Z3: Proven-win override — a candidate whose completed search proves a win is
|
||||
played even if the heuristic preferred another move.
|
||||
Z4: Elapsed-time rollout gate — Zenith keeps a larger timeout reserve than
|
||||
Prism. The inherited multiplayer "deepen when > 250 ms remain" gate is
|
||||
lowered by that extra reserve, so 3-snake rollouts deepen after the same
|
||||
elapsed time as Prism instead of never reaching depth 3. The duel gate is
|
||||
left alone: the verdict pass already spends the duel budget.
|
||||
"""
|
||||
from time import perf_counter
|
||||
|
||||
@@ -27,18 +32,22 @@ _PROVEN_WIN = BitboardDuelSearch.WIN / 2
|
||||
_PROVEN_LOSS = BitboardDuelSearch.LOSS / 2
|
||||
# Reserve kept for Apex's history bookkeeping after the verdict pass.
|
||||
_VERDICT_RESERVE_MS = 25.0
|
||||
_ZENITH_TIMEOUT_BUFFER_MS = 180
|
||||
|
||||
class ZenithBattleSnake_ClaudeOpus5_5(ZenithSurvivalMixin, PrismBattleSnake_GPT_5_6_Sol):
|
||||
VERSION = "1.1.0"
|
||||
VERSION = "1.2.0"
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.name = "ZenithBattleSnake"
|
||||
self.version = self.VERSION
|
||||
# Z4: deepen after the same elapsed time as the inherited Prism gates.
|
||||
extra_reserve = self._get_timeout_buffer_ms() - super()._get_timeout_buffer_ms()
|
||||
self._rollout_deepen_ms = max(120.0, self._rollout_deepen_ms - extra_reserve)
|
||||
|
||||
def _get_timeout_buffer_ms(self):
|
||||
# Leave room for executor scheduling, history, JSON and network delivery.
|
||||
return max(180, super()._get_timeout_buffer_ms())
|
||||
return max(_ZENITH_TIMEOUT_BUFFER_MS, super()._get_timeout_buffer_ms())
|
||||
|
||||
def _choose_duel_move(
|
||||
self, safe_moves, my_body, my_len, my_health, other_snakes, food_set,
|
||||
|
||||
Reference in New Issue
Block a user