diff --git a/snakes/BetterMasterSnake.py b/snakes/BetterMasterSnake.py index 1fc01ed..299366b 100644 --- a/snakes/BetterMasterSnake.py +++ b/snakes/BetterMasterSnake.py @@ -4,7 +4,7 @@ from collections import deque class BetterMasterSnake(TemplateSnake): def __init__(self): super().__init__() - self.name = "CloseToBodySnake" + self.name = "BetterMasterSnake" self.disabled_find_near_by_food = True # Definiere die möglichen Bewegungsrichtungen self.min_safe_area = 2 @@ -36,7 +36,7 @@ class BetterMasterSnake(TemplateSnake): snake.pop() return snake - def avoid_my_body(self, my_body:dict) -> list: + def avoid_my_body(self) -> 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} ] @@ -47,29 +47,28 @@ class BetterMasterSnake(TemplateSnake): """ remove = [] for direction, location in self.safe_positions.items(): - if location in my_body: + if location in self.my_body: remove.append(direction) for direction in remove: del self.safe_positions[direction] + self.add_calculations({"function": "avoid_my_body", "my_body": self.my_body, "safe_positions": self.safe_positions}) - def avoid_walls(self, board_width:int, board_height:int): + def avoid_walls(self): remove = [] 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) + x_out_range = (location["x"] < 0 or location["x"] == self.board_width) + y_out_range = (location["y"] < 0 or location["y"] == self.board_height) if x_out_range or y_out_range: remove.append(direction) for direction in remove: del self.safe_positions[direction] + self.add_calculations({"function": "avoid_walls", "board_width": self.board_width, "board_height": self.board_height, "safe_positions": self.safe_positions}) - def avoid_snakes(self, snakes:list): + def avoid_snakes(self): remove = [] - for snake in snakes: - if snake["id"] == self.my_snake["id"]: - continue - + for snake in self.other_snakes: for direction, location in self.safe_positions.items(): if self.game_type == "constrictor": if location in snake["body"]: @@ -81,13 +80,11 @@ class BetterMasterSnake(TemplateSnake): remove = set(remove) for direction in remove: del self.safe_positions[direction] + self.add_calculations({"function": "avoid_snakes", "other_snakes": self.other_snakes, "safe_positions": self.safe_positions}) - def avoid_get_eaten_by_other_snakes(self, snakes:list): + def avoid_get_eaten_by_other_snakes(self): remove = [] - for snake in snakes: - if snake["id"] == self.my_snake["id"]: - continue - + for snake in self.other_snakes: 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()]: @@ -99,23 +96,28 @@ class BetterMasterSnake(TemplateSnake): remove = set(remove) for direction in remove: del self.safe_positions[direction] + self.add_calculations({"function": "avoid_get_eaten_by_other_snakes", "other_snakes": self.other_snakes, "safe_positions": self.safe_positions}) def find_safe_positions(self): self.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) + self.add_calculations({"function": "get_possible_moves", "safe_positions": self.safe_positions}) + + self.avoid_my_body() + self.avoid_walls() + self.avoid_snakes() + self.avoid_get_eaten_by_other_snakes() def choose_move(self, game_data): + move = None self.calculations = [] self.eat_the_snake_overwrite = False - move = None self.board_width = game_data['board']['width'] self.board_height = game_data['board']['height'] - self.snakes = game_data['board']['snakes'] + self.my_snake = game_data['you'] + self.other_snakes = [ x for x in game_data['board']['snakes'] if x["id"] != self.my_snake["id"] ] + self.my_head = self.my_snake['head'] self.my_body = self.my_snake["body"] self.food_positions = game_data['board']['food'] @@ -123,12 +125,12 @@ class BetterMasterSnake(TemplateSnake): 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": self.safe_positions}) + self.add_calculations({"function": "eat_the_snake_overwrite", "my_head": self.my_head, "move": move}) return self.safe_positions if self.game_type == "constrictor": move = self.ensure_escape_route(self.find_direction()) - self.add_calculations({"function": "find_direction", "my_head": self.my_head, "move": move, "safe_positions": self.safe_positions}) + self.add_calculations({"function": "find_direction", "my_head": self.my_head, "move": move}) else: # Finde den besten Weg zur Nahrung if self.is_food_nearby() or self.disabled_find_near_by_food: @@ -139,11 +141,11 @@ class BetterMasterSnake(TemplateSnake): if not move: 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}) + self.add_calculations({"function": "move_close_to_body", "my_head": self.my_head, "move": move}) # Überprfe, ob der Zug einen Ausweg lässt 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}) + self.add_calculations({"function": "ensure_escape_route", "my_head": self.my_head, "move": move}) self.add_to_history(self.calculations) return move if move else "up" @@ -161,10 +163,9 @@ class BetterMasterSnake(TemplateSnake): # Exclude own snake's body from obstacles obstacles = set((part['x'], part['y']) for part in self.my_body) - for snake in self.snakes: - if snake['id'] != self.my_snake['id']: - for part in snake['body']: - obstacles.add((part['x'], part['y'])) + for snake in self.other_snakes: + for part in snake['body']: + obstacles.add((part['x'], part['y'])) # Choose the closest food source based on the heuristic closest_food = min(self.food_positions, key=lambda food: abs(food['x'] - self.my_head['x']) + abs(food['y'] - self.my_head['y'])) @@ -172,14 +173,13 @@ class BetterMasterSnake(TemplateSnake): # 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) return path - + def find_path_to_tail(self): # Exclude other snake's body from obstacles obstacles = set() - for snake in self.snakes: - if snake['id'] != self.my_snake['id']: - for part in snake['body']: - obstacles.add((part['x'], part['y'])) + for snake in self.other_snakes: + for part in snake['body']: + obstacles.add((part['x'], part['y'])) my_snake_tail = {"x": self.my_body[-1]['x'], "y": self.my_body[-1]['y']}