update UltimateBattleSnake to 4.2.0
Build and Push Docker Container / build-and-push (push) Successful in 1m12s
Build and Push Docker Container / build-and-push (push) Successful in 1m12s
This commit is contained in:
@@ -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
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user