update UltimateBattleSnake to 4.2.0
Build and Push Docker Container / build-and-push (push) Successful in 1m12s

This commit is contained in:
2026-04-05 03:05:46 +02:00
parent 643f4b468e
commit 00d55b5419
2 changed files with 22 additions and 12 deletions
+21 -11
View File
@@ -10,7 +10,7 @@ from server.dataset.RLBootstrapDataset import RLBootstrapDataset
class UltimateBattleSnake(TemplateSnake):
"""
UltimateBattleSnake v4.0.0
UltimateBattleSnake v4.2.0
All improvements over BestBattleSnake:
v3: #1+#9 Simultaneous minimax (both snakes move at once) with hazard/health tracking
@@ -39,9 +39,12 @@ class UltimateBattleSnake(TemplateSnake):
v4.1 B1 _simulation_blocked now correctly keeps enemy tail blocked when enemy_can_grow=True
v4.1 B2 _build_enemy_attack_map: can_en_tail=False when enemy is about to eat (won't vacate)
v4.1 B3 _compute_base_blocked: same enemy_can_grow fix for Voronoi dmap accuracy
v4.2 B4 _build_enemy_attack_map: enemy_can_grow now actually passed from choose_move and tree
v4.2 B5 _choose_duel_move: removed double food bias (score_move already adds it; duel now only adjusts delta)
v4.2 B6 _minimax_sim: occupancy now respects _is_tail_stacked (stacked tail not vacated)
"""
VERSION = "4.1.0"
VERSION = "4.2.0"
Point = tuple[int, int]
Coord = dict[str, int]
SnakeState = dict[str, Any]
@@ -178,6 +181,7 @@ class UltimateBattleSnake(TemplateSnake):
enemy_attack_map = self._build_enemy_attack_map(
my_snake=my_snake, other_snakes=other_snakes, food_set=food_set,
is_constrictor=is_constrictor, width=width, height=height,
enemy_can_grow=enemy_can_grow,
)
safe_moves = self._legal_moves(
@@ -252,7 +256,6 @@ class UltimateBattleSnake(TemplateSnake):
) -> tuple[str, dict[str, float]]:
scores: dict[str, float] = {}
safety: dict[str, dict] = {}
enemy_heads = self._enemy_heads
for move, pos in safe_moves.items():
if self._time_exceeded(deadline):
@@ -382,11 +385,14 @@ class UltimateBattleSnake(TemplateSnake):
if dist == 1:
sc -= 180.0 * dw["distance_safety"]
# Override food bias with duel style weight
# Apply duel-style food multiplier on top of the base food bias already added by _score_move.
# _score_move contributes (30+80*hunger)/(nearest_food+1); here we scale that contribution
# by (dw["food_bias"] - 1) so the net effect is the full duel-weighted amount.
nearest_food = info.get("nearest_food")
if nearest_food is not None:
if nearest_food is not None and dw["food_bias"] != 1.0:
hunger = max(0.0, (65.0 - my_health) / 65.0)
sc += ((25.0 + 90.0 * hunger) * dw["food_bias"]) / (nearest_food + 1)
base_food_contribution = (30.0 + 80.0 * hunger) / (nearest_food + 1)
sc += base_food_contribution * (dw["food_bias"] - 1.0)
sc += self._territory_fast(point, blocked, width, height, deadline) * 0.55
scores[move] = round(sc, 5)
@@ -475,7 +481,6 @@ class UltimateBattleSnake(TemplateSnake):
) -> tuple[str, dict[str, float]]:
scores: dict[str, float] = {}
safety: dict[str, dict] = {}
enemy_heads = self._enemy_heads
for move, pos in safe_moves.items():
if self._time_exceeded(deadline):
@@ -821,9 +826,14 @@ class UltimateBattleSnake(TemplateSnake):
my_h = my_body[0]
en_h = enemy_body[0]
# Occupied: bodies excluding tails (tails vacate this turn)
my_occ = {(s["x"], s["y"]) for s in my_body[:-1]}
en_occ = {(s["x"], s["y"]) for s in enemy_body[:-1]}
# Occupied: bodies excluding tails that will vacate this turn.
# A tail only vacates if the snake is NOT stacked (i.e. didn't eat food last turn).
my_occ = {(s["x"], s["y"]) for s in my_body}
if not self._is_tail_stacked(my_body):
my_occ.discard((my_body[-1]["x"], my_body[-1]["y"]))
en_occ = {(s["x"], s["y"]) for s in enemy_body}
if not self._is_tail_stacked(enemy_body):
en_occ.discard((enemy_body[-1]["x"], enemy_body[-1]["y"]))
all_occ = my_occ | en_occ
my_moves = []
@@ -1019,7 +1029,7 @@ class UltimateBattleSnake(TemplateSnake):
# Build attack map for safe option count
future_snake = {"head": my_body[0], "body": my_body, "length": len(my_body), "id": "__future__"}
atk = self._build_enemy_attack_map(future_snake, other_snakes, food_set, is_constrictor, width, height)
atk = self._build_enemy_attack_map(future_snake, other_snakes, food_set, is_constrictor, width, height, enemy_can_grow)
en_safe = self._safe_next_options(my_body, len(my_body), blocked, atk, food_set, is_constrictor, width, height)
# Zero safe options = will be forced into a losing head-to-head next turn
+1 -1
View File
@@ -8,7 +8,7 @@ SNAKE_REGISTRY = {
"BetterMasterSnake": "1.3.0",
"BestBattleSnake": "2.6.0",
"TrainedBattleSnake": "0.1.0",
"UltimateBattleSnake": "4.1.0",
"UltimateBattleSnake": "4.2.0",
}
def build_snake(selected_snake: str):