The leading agent on Snake, random start, written by a language model.
import random
from collections import deque
def get_move(state):
my_snake = state['my_snake']
enemy_snake = state.get('enemy_snake')
my_head = tuple(my_snake[0])
my_len = len(my_snake)
enemy_head = None
enemy_len = 0
if enemy_snake and len(enemy_snake) > 0:
enemy_head = tuple(enemy_snake[0])
enemy_len = len(enemy_snake)
w, h = state['grid_size']
food_set = set(tuple(f) for f in state['food'])
turn = state['turn']
memory = state.get('memory', {})
# Cache walls once per game - convert to set of tuples
if 'wall_set' not in memory:
walls_list = state.get('walls', [])
memory['wall_set'] = set()
for wall in walls_list:
if isinstance(wall, (list, tuple)):
memory['wall_set'].add(tuple(wall))
else:
memory['wall_set'].add(wall)
walls = memory['wall_set']
body = set(tuple(b) for b in my_snake)
enemy = set()
if enemy_snake:
enemy = set(tuple(e) for e in enemy_snake)
occupied_base = body | enemy | walls
def get_safe_moves(head, occupied_set):
moves = {
'UP': (head[0], head[1] - 1),
'DOWN': (head[0], head[1] + 1),
'LEFT': (head[0] - 1, head[1]),
'RIGHT': (head[0] + 1, head[1]),
}
safe = {}
for m, pos in moves.items():
if 0 < pos[0] < w - 1 and 0 < pos[1] < h - 1 and pos not in occupied_set:
safe[m] = pos
return safe
my_safe = get_safe_moves(my_head, occupied_base)
if not my_safe:
return 'UP'
# Count reachable space from a position
def count_reachable(pos, blocked_set):
visited = {pos}
queue = deque([pos])
dirs = [(0, -1), (0, 1), (-1, 0), (1, 0)]
while queue:
curr = queue.popleft()
for dx, dy in dirs:
next_pos = (curr[0] + dx, curr[1] + dy)
if (0 < next_pos[0] < w - 1 and 0 < next_pos[1] < h - 1 and
next_pos not in visited and next_pos not in blocked_set):
visited.add(next_pos)
queue.append(next_pos)
return len(visited)
# Wall-aware Voronoi: distance to nearest position controlled by opponent
def dual_bfs_voronoi(my_pos, en_pos, occupied):
if en_pos is None:
en_pos = my_pos
visited = {my_pos: 0, en_pos: 0}
queue = deque([(my_pos, 'mine'), (en_pos, 'enemy')])
dirs = [(0, -1), (0, 1), (-1, 0), (1, 0)]
while queue:
(x, y), owner = queue.popleft()
for dx, dy in dirs:
next_pos = (x + dx, y + dy)
if (0 < next_pos[0] < w - 1 and 0 < next_pos[1] < h - 1 and
next_pos not in visited and next_pos not in occupied):
visited[next_pos] = owner
queue.append((next_pos, owner))
return visited
# Distance to nearest food
def dist_to_food(pos, food_set):
if not food_set:
return float('inf')
visited = {pos}
queue = deque([(pos, 0)])
dirs = [(0, -1), (0, 1), (-1, 0), (1, 0)]
while queue:
(x, y), dist = queue.popleft()
if (x, y) in food_set:
return dist
for dx, dy in dirs:
next_pos = (x + dx, y + dy)
if (0 < next_pos[0] < w - 1 and 0 < next_pos[1] < h - 1 and
next_pos not in visited and next_pos not in occupied_base):
visited.add(next_pos)
queue.append((next_pos, dist + 1))
return float('inf')
# Evaluate each safe move
best_move = None
best_score = float('-inf')
voronoi = dual_bfs_voronoi(my_head, enemy_head, occupied_base)
for move, next_pos in my_safe.items():
# Evaluate space control after this move
new_occupied = occupied_base - {tuple(my_snake[-1])} | {next_pos}
my_space = count_reachable(next_pos, new_occupied - body)
# Aggressive food interception (turns 0-100)
food_dist = dist_to_food(next_pos, food_set)
food_score = 0
if turn < 100 and food_dist != float('inf'):
food_score = 100 / (food_dist + 1)
# Voronoi territory control
my_territory = sum(1 for pos, owner in voronoi.items() if owner == 'mine')
enemy_territory = sum(1 for pos, owner in voronoi.items() if owner == 'enemy')
# Check if next position is in my territory (Voronoi advantage)
voronoi_bonus = 5 if voronoi.get(next_pos) == 'mine' else -3
# Prefer moves that expand space and deny enemy food
space_score = my_space * 0.5
# Avoid moving into enemy territory too aggressively unless we're longer
territory_score = 0
if my_len > enemy_len:
territory_score = voronoi_bonus * 2
else:
territory_score = voronoi_bonus
# Distance to enemy head (aggressive early game)
aggression_score = 0
if enemy_head:
enemy_dist = abs(next_pos[0] - enemy_head[0]) + abs(next_pos[1] - enemy_head[1])
if turn < 80 and my_len >= enemy_len - 1:
aggression_score = 50 / (enemy_dist + 1)
# Total score
score = space_score + food_score + territory_score + aggression_score
if score > best_score:
best_score = score
best_move = move
return best_move if best_move else 'UP'