change code to store safe_positions in class and remove self.directions
This commit is contained in:
+47
-62
@@ -8,15 +8,9 @@ class BetterMasterSnake(TemplateSnake):
|
||||
self.disabled_find_near_by_food = True
|
||||
# Definiere die möglichen Bewegungsrichtungen
|
||||
self.min_safe_area = 2
|
||||
self.directions = {
|
||||
'up': (0, -1),
|
||||
'down': (0, 1),
|
||||
'left': (-1, 0),
|
||||
'right': (1, 0)
|
||||
}
|
||||
|
||||
def get_possible_moves(self, my_head):
|
||||
return {
|
||||
self.safe_positions = {
|
||||
"up": {
|
||||
"x": my_head["x"],
|
||||
"y": my_head["y"] + 1
|
||||
@@ -42,7 +36,7 @@ class BetterMasterSnake(TemplateSnake):
|
||||
snake.pop()
|
||||
return snake
|
||||
|
||||
def avoid_my_body(self, my_body, possible_moves:dict) -> list:
|
||||
def avoid_my_body(self, my_body:dict) -> list:
|
||||
"""
|
||||
my_body: List of dictionaries of x/y coordinates for every segment of a Battlesnake.
|
||||
e.g. [ {"x": 0, "y": 0}, {"x": 1, "y": 0}, {"x": 2, "y": 0} ]
|
||||
@@ -52,52 +46,46 @@ class BetterMasterSnake(TemplateSnake):
|
||||
return: The list of remaining possible_moves, with the 'neck' direction removed
|
||||
"""
|
||||
remove = []
|
||||
for direction, location in possible_moves.items():
|
||||
for direction, location in self.safe_positions.items():
|
||||
if location in my_body:
|
||||
remove.append(direction)
|
||||
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
del self.safe_positions[direction]
|
||||
|
||||
return possible_moves
|
||||
|
||||
def avoid_walls(self, board_width:int, board_height:int, possible_moves:dict):
|
||||
def avoid_walls(self, board_width:int, board_height:int):
|
||||
remove = []
|
||||
for direction, location in list(possible_moves.items()):
|
||||
for direction, location in list(self.safe_positions.items()):
|
||||
x_out_range = (location["x"] < 0 or location["x"] == board_width)
|
||||
y_out_range = (location["y"] < 0 or location["y"] == board_height)
|
||||
if x_out_range or y_out_range:
|
||||
remove.append(direction)
|
||||
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
del self.safe_positions[direction]
|
||||
|
||||
return possible_moves
|
||||
|
||||
def avoid_snakes(self, snakes:list, possible_moves:dict):
|
||||
def avoid_snakes(self, snakes:list):
|
||||
remove = []
|
||||
for snake in snakes:
|
||||
if snake["id"] == self.my_snake["id"]:
|
||||
continue
|
||||
|
||||
for direction, location in possible_moves.items():
|
||||
for direction, location in self.safe_positions.items():
|
||||
if location in self.get_snake_body_without_snake_tail(snake["body"]):
|
||||
remove.append(direction)
|
||||
|
||||
remove = set(remove)
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
del self.safe_positions[direction]
|
||||
|
||||
return possible_moves
|
||||
|
||||
def avoid_get_eaten_by_other_snakes(self, snakes:list, possible_moves:dict):
|
||||
def avoid_get_eaten_by_other_snakes(self, snakes:list):
|
||||
remove = []
|
||||
for snake in snakes:
|
||||
if snake["id"] == self.my_snake["id"]:
|
||||
continue
|
||||
|
||||
for direction, location in possible_moves.items():
|
||||
if len(possible_moves) > 1:
|
||||
for direction, location in self.safe_positions.items():
|
||||
if len(self.safe_positions) > 1:
|
||||
if snake["length"] < self.my_snake["length"] and location in [{"x": v["x"], "y": v["y"]} for k, v in self.get_possible_moves(snake["head"]).items()]:
|
||||
self.eat_the_snake_overwrite = True
|
||||
return direction
|
||||
@@ -106,17 +94,14 @@ class BetterMasterSnake(TemplateSnake):
|
||||
|
||||
remove = set(remove)
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
return possible_moves
|
||||
del self.safe_positions[direction]
|
||||
|
||||
def find_safe_positions(self):
|
||||
safe_positions = self.get_possible_moves(self.my_head)
|
||||
safe_positions = self.avoid_my_body(self.my_body, safe_positions)
|
||||
safe_positions = self.avoid_walls(self.board_width, self.board_height, safe_positions)
|
||||
safe_positions = self.avoid_snakes(self.snakes, safe_positions)
|
||||
safe_positions = self.avoid_get_eaten_by_other_snakes(self.snakes, safe_positions)
|
||||
|
||||
return safe_positions
|
||||
self.get_possible_moves(self.my_head)
|
||||
self.avoid_my_body(self.my_body)
|
||||
self.avoid_walls(self.board_width, self.board_height)
|
||||
self.avoid_snakes(self.snakes)
|
||||
self.avoid_get_eaten_by_other_snakes(self.snakes)
|
||||
|
||||
def choose_move(self, game_data):
|
||||
self.calculations = []
|
||||
@@ -131,10 +116,10 @@ class BetterMasterSnake(TemplateSnake):
|
||||
self.my_body = self.my_snake["body"]
|
||||
self.food_positions = game_data['board']['food']
|
||||
|
||||
safe_positions = self.find_safe_positions()
|
||||
self.find_safe_positions()
|
||||
if self.eat_the_snake_overwrite:
|
||||
self.add_calculations({"function": "eat_the_snake_overwrite", "my_head": self.my_head, "move": move, "safe_positions": safe_positions})
|
||||
return safe_positions
|
||||
self.add_calculations({"function": "eat_the_snake_overwrite", "my_head": self.my_head, "move": move, "safe_positions": self.safe_positions})
|
||||
return self.safe_positions
|
||||
|
||||
# Finde die nächstgelegene Nahrungsquelle, wenn Nahrung vorhanden ist
|
||||
try:
|
||||
@@ -142,19 +127,19 @@ class BetterMasterSnake(TemplateSnake):
|
||||
if self.is_food_nearby() or self.disabled_find_near_by_food:
|
||||
path_to_food = self.find_path_to_food()
|
||||
if path_to_food:
|
||||
move = self.move_towards(path_to_food[0], safe_positions)
|
||||
move = self.move_towards(path_to_food[0])
|
||||
self.add_calculations({"function": "move_towards", "my_head": self.my_head, "path_to_food": path_to_food, "move": move})
|
||||
|
||||
if not move:
|
||||
move = self.move_close_to_body(safe_positions)
|
||||
self.add_calculations({"function": "move_close_to_body", "my_head": self.my_head, "move": move, "safe_positions": safe_positions})
|
||||
move = self.move_close_to_body()
|
||||
self.add_calculations({"function": "move_close_to_body", "my_head": self.my_head, "move": move, "safe_positions": self.safe_positions})
|
||||
|
||||
# Überprfe, ob der Zug einen Ausweg lässt
|
||||
move = self.ensure_escape_route(move, safe_positions)
|
||||
self.add_calculations({"function": "ensure_escape_route", "my_head": self.my_head, "move": move, "safe_positions": safe_positions})
|
||||
move = self.ensure_escape_route(move)
|
||||
self.add_calculations({"function": "ensure_escape_route", "my_head": self.my_head, "move": move, "safe_positions": self.safe_positions})
|
||||
except ValueError:
|
||||
move = self.ensure_escape_route(self.find_direction(safe_positions), safe_positions)
|
||||
self.add_calculations({"function": "ValueError - find_direction", "my_head": self.my_head, "move": move, "safe_positions": safe_positions})
|
||||
move = self.ensure_escape_route(self.find_direction())
|
||||
self.add_calculations({"function": "ValueError - find_direction", "my_head": self.my_head, "move": move, "safe_positions": self.safe_positions})
|
||||
|
||||
self.add_to_history(self.calculations)
|
||||
return move if move else "up"
|
||||
@@ -198,10 +183,10 @@ class BetterMasterSnake(TemplateSnake):
|
||||
path = self.a_star_search(self.my_head, my_snake_tail, obstacles, self.board_width, self.board_height)
|
||||
return path
|
||||
|
||||
def move_towards(self, target, safe_positions):
|
||||
def move_towards(self, target):
|
||||
best_direction = None
|
||||
min_distance = float('inf')
|
||||
for direction, coords in safe_positions.items():
|
||||
for direction, coords in self.safe_positions.items():
|
||||
distance = abs(target['x'] - coords['x']) + abs(target['y'] - coords['y'])
|
||||
if distance < min_distance:
|
||||
min_distance = distance
|
||||
@@ -209,14 +194,14 @@ class BetterMasterSnake(TemplateSnake):
|
||||
|
||||
return best_direction if best_direction else "up"
|
||||
|
||||
def move_close_to_body(self, safe_positions):
|
||||
def move_close_to_body(self):
|
||||
# Heuristik, um Positionen nahe dem eigenen Körper zu bevorzugen
|
||||
body_positions = set((part['x'], part['y']) for part in self.my_body)
|
||||
best_move = None
|
||||
best_score = float('inf')
|
||||
for direction, (dx, dy) in self.directions.items():
|
||||
next_position = (self.my_head['x'] + dx, self.my_head['y'] + dy)
|
||||
if next_position in safe_positions:
|
||||
for direction, pos in self.safe_positions.items():
|
||||
next_position = (pos['x'], pos['y'])
|
||||
if next_position in self.safe_positions:
|
||||
# Berechne die Distanz zum eigenen Körper
|
||||
distance_to_body = min(abs(next_position[0] - part[0]) + abs(next_position[1] - part[1]) for part in body_positions)
|
||||
if distance_to_body < best_score:
|
||||
@@ -224,20 +209,20 @@ class BetterMasterSnake(TemplateSnake):
|
||||
best_move = direction
|
||||
return best_move if best_move else "up" # Standardbewegung, falls keine bessere gefunden wird
|
||||
|
||||
def ensure_escape_route(self, move, safe_positions):
|
||||
def ensure_escape_route(self, move):
|
||||
try:
|
||||
future_position = safe_positions[move]
|
||||
future_position = self.safe_positions[move]
|
||||
except KeyError:
|
||||
for move, pos in safe_positions.items():
|
||||
for move, pos in self.safe_positions.items():
|
||||
if self.is_near_tail((pos["x"], pos["y"]), (self.my_body[-1]['x'], self.my_body[-1]['y'])):
|
||||
self.add_calculations({"function": "ensure_escape_route", "move": move, "is_near_tail": True})
|
||||
move = self.move_towards(pos, safe_positions)
|
||||
move = self.move_towards(pos)
|
||||
return move
|
||||
else:
|
||||
path_to_tail = self.find_path_to_tail()
|
||||
if path_to_tail:
|
||||
self.add_calculations({"function": "move_towards", "my_head": self.my_head, "path_to_tail": path_to_tail, "move": move})
|
||||
move = self.move_towards(path_to_tail[0], safe_positions)
|
||||
move = self.move_towards(path_to_tail[0])
|
||||
|
||||
self.add_calculations({"function": "ensure_escape_route", "move": move, "KeyError": "Snake Coild itself up"})
|
||||
return move
|
||||
@@ -257,9 +242,9 @@ class BetterMasterSnake(TemplateSnake):
|
||||
# TODO: Fix - Snake Neat to find the best way - Close to the Tail and maybe fill most free cells as posible
|
||||
#if accessible_area_count < self.min_safe_area:
|
||||
# # Finde den nächstgelegenen Zug zum Schwanz
|
||||
# closest_move = min(safe_positions.keys(), key=lambda m: self.distance_to_tail(safe_positions[m], tail_position))
|
||||
# closest_move = min(self.safe_positions.keys(), key=lambda m: self.distance_to_tail(self.safe_positions[m], tail_position))
|
||||
# # Überprüfe, ob der nächstgelegene Zug eine größere zugängliche Fläche hat
|
||||
# if self.flood_fill_count(safe_positions[closest_move], [(part['x'], part['y']) for part in self.my_body]) >= self.min_safe_area:
|
||||
# if self.flood_fill_count(self.safe_positions[closest_move], [(part['x'], part['y']) for part in self.my_body]) >= self.min_safe_area:
|
||||
# return closest_move
|
||||
|
||||
return move
|
||||
@@ -273,7 +258,7 @@ class BetterMasterSnake(TemplateSnake):
|
||||
current = queue.popleft()
|
||||
if current not in visited:
|
||||
visited.add(current)
|
||||
for direction, pos in self.directions.items():
|
||||
for direction, pos in self.safe_positions.items():
|
||||
neighbor = (current[0] + pos[0], current[1] + pos[1])
|
||||
if (neighbor not in visited and neighbor not in body_set and
|
||||
0 <= neighbor[0] < self.board_width and
|
||||
@@ -343,12 +328,12 @@ class BetterMasterSnake(TemplateSnake):
|
||||
|
||||
return None # Kein Pfad gefunden
|
||||
|
||||
def find_direction(self, safe_positions):
|
||||
def find_direction(self):
|
||||
# Beispielhafte Logik zur Auswahl einer Bewegungsrichtung
|
||||
for direction, (dx, dy) in self.directions.items():
|
||||
next_position = (self.my_head['x'] + dx, self.my_head['y'] + dy)
|
||||
for direction, pos in self.safe_positions.items():
|
||||
next_position = (pos['x'], pos['y'])
|
||||
# Konvertiere safe_positions in eine Liste von Tupeln für den Vergleich
|
||||
safe_positions_tuples = [(pos['x'], pos['y']) for pos in safe_positions.values()]
|
||||
safe_positions_tuples = [(pos['x'], pos['y']) for pos in self.safe_positions.values()]
|
||||
if next_position in safe_positions_tuples:
|
||||
return direction
|
||||
return "up" # Standardbewegung, falls keine sichere Position gefunden wird
|
||||
|
||||
Reference in New Issue
Block a user