diff --git a/snakes/BetterMasterSnake.py b/snakes/BetterMasterSnake.py index 20368ca..51e3f69 100644 --- a/snakes/BetterMasterSnake.py +++ b/snakes/BetterMasterSnake.py @@ -70,12 +70,12 @@ class BetterMasterSnake(TemplateSnake): remove = [] for snake in self.other_snakes: for direction, location in self.safe_positions.items(): - if self.game_type == "constrictor": + #if self.game_type == "constrictor": if location in snake["body"]: remove.append(direction) - else: - if location in self.get_snake_body_without_snake_tail(snake["body"]): - remove.append(direction) + #else: + # if location in self.get_snake_body_without_snake_tail(snake["body"]): + # remove.append(direction) remove = set(remove) for direction in remove: @@ -123,6 +123,8 @@ class BetterMasterSnake(TemplateSnake): self.food_positions = game_data['board']['food'] self.game_type = game_data['game']["ruleset"]["name"] + self.board = game_data['board'] + self.find_safe_positions() if self.eat_the_snake_overwrite: if len(self.safe_positions) > 1: @@ -177,12 +179,12 @@ class BetterMasterSnake(TemplateSnake): closest_food = min(self.food_positions, key=lambda food: abs(food['x'] - self.my_head['x']) + abs(food['y'] - self.my_head['y'])) # Use A* to search for a safe path - path = self.a_star_search(self.my_head, closest_food, obstacles, self.board_width, self.board_height) + path = self.a_star_search(self.my_head, closest_food, obstacles) return path def find_path_to_tail(self): # Exclude other snake's body from obstacles - obstacles = set() + obstacles = set((part['x'], part['y']) for part in self.my_body) for snake in self.other_snakes: for part in snake['body']: obstacles.add((part['x'], part['y'])) @@ -190,7 +192,7 @@ class BetterMasterSnake(TemplateSnake): my_snake_tail = {"x": self.my_body[-1]['x'], "y": self.my_body[-1]['y']} # Use A* to search for a safe path - path = self.a_star_search(self.my_head, my_snake_tail, obstacles, self.board_width, self.board_height) + path = self.a_star_search(self.my_head, my_snake_tail, obstacles) return path def move_towards(self, target): @@ -235,63 +237,46 @@ class BetterMasterSnake(TemplateSnake): move = self.move_towards(path_to_tail[0]) self.add_calculations({"function": "ensure_escape_route", "move": move, "KeyError": "Snake Coild itself up"}) - return move - return move - - future_coords = (future_position['x'], future_position['y']) - tail_position = (self.my_body[-1]['x'], self.my_body[-1]['y']) - - accessible_area_count = self.flood_fill_count(future_coords, [(part['x'], part['y']) for part in self.my_body]) - self.add_calculations({ - "function": "flood_fill_count", - "move": move, - "future_coords": future_coords, - "tail_position": tail_position, - "accessible_area_count": accessible_area_count, - }) + #return move # 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 - # print(self.safe_positions.keys()) - # closest_move = min(self.safe_positions.keys(), key=lambda m: self.distance_to_tail(self.safe_positions[m], tail_position)) - # accessible_area_count = self.flood_fill_count((self.safe_positions[closest_move]["x"], self.safe_positions[closest_move]["y"]), [(part['x'], part['y']) for part in self.my_body]) - - # print(closest_move, accessible_area_count, accessible_area_count >= self.min_safe_area) - # # Überprüfe, ob der nächstgelegene Zug eine größere zugängliche Fläche hat - # if accessible_area_count >= self.min_safe_area: - # return closest_move + #if self.will_end_in_dead_end(self.safe_positions[move], depth=20): + # return move return move - def flood_fill_count(self, start, body): - visited = set() - queue = deque([start]) - body_set = set(body) + def will_end_in_dead_end(self, start, depth=10): + start = (start['x'], start['y']) + return self.dfs_dead_end(self.board, start, depth, set([start])) - while queue: - current = queue.popleft() - if current not in visited: - visited.add(current) - for direction, pos in self.safe_positions.items(): - neighbor = (pos["x"], pos["y"]) - if (neighbor not in visited and neighbor not in body_set and - 0 <= neighbor[0] < self.board_width and - 0 <= neighbor[1] < self.board_height): - queue.append(neighbor) + def dfs_dead_end(self, board, position, depth, path): + # Abbruchbedingung der Rekursion: Wenn Tiefe erreicht ist + if depth == 0: + return False # Nicht genügend Tiefe, um eine Sackgasse zu bestätigen - return len(visited) + # Bewege nach oben + next_position = position + if next_position[0] < 0 or next_position in board['snakes'] or next_position in path: + return True # Sackgasse gefunden + + # Füge aktuelle Position zum Pfad hinzu + path.add(next_position) + # Rekursive Überprüfung der nächsten Position + result = self.dfs_dead_end(board, next_position, depth - 1, path) + # Entferne aktuelle Position vom Pfad + path.remove(next_position) + return result + + def is_position_safe(self, position): + return 0 <= position['x'] < self.board_width and 0 <= position['y'] < self.board_height and (position['x'], position['y']) not in self.my_body def is_near_tail(self, position, tail): return abs(position["x"] - tail[0]) + abs(position["y"] - tail[1]) <= 2 - def distance_to_tail(self, position, tail): - return abs(position["x"] - tail[0]) + abs(position["y"] - tail[1]) - - def a_star_search(self, start, goal, obstacles, board_width, board_height): + def a_star_search(self, start, goal, obstacles): # Helper functions def is_position_safe(position): - return 0 <= position['x'] < board_width and 0 <= position['y'] < board_height and (position['x'], position['y']) not in obstacles + return 0 <= position['x'] < self.board_width and 0 <= position['y'] < self.board_height and (position['x'], position['y']) not in obstacles def get_neighbors(position): neighbors = []