diff --git a/snakes/BetterMasterSnake.py b/snakes/BetterMasterSnake.py index 3253aad..ae9a7c9 100644 --- a/snakes/BetterMasterSnake.py +++ b/snakes/BetterMasterSnake.py @@ -26,7 +26,7 @@ class BetterMasterSnake(TemplateSnake): self.board = game_data['board'] - self.find_safe_positions() + self.safe_positions = self.find_safe_positions(add_to_calculations=True) if self.eat_the_snake_overwrite: return self.overwrite_eat_the_other_snake(game_data["turn"]) diff --git a/snakes/TemplateSnake.py b/snakes/TemplateSnake.py index 05f486a..c323ae0 100644 --- a/snakes/TemplateSnake.py +++ b/snakes/TemplateSnake.py @@ -32,7 +32,7 @@ class TemplateSnake: self.food_positions = game_data['board']['food'] self.game_type = game_data['game']["ruleset"]["name"] - self.find_safe_positions() + self.safe_positions = self.find_safe_positions(add_to_calculations=True) moves = list(self.safe_positions.keys()) if len(moves) > 0: move = random.choice(moves) @@ -70,7 +70,7 @@ class TemplateSnake: snake.pop() return snake - def avoid_my_body(self) -> list: + def avoid_my_body(self, my_body:list[dict], safe_positions:dict[str, dict], add_to_calculations:bool=False) -> 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} ] @@ -80,32 +80,38 @@ class TemplateSnake: return: The list of remaining possible_moves, with the 'neck' direction removed """ remove = [] - for direction, location in self.safe_positions.items(): - if location in self.my_body: + for direction, location in safe_positions.items(): + if location in my_body: remove.append(direction) for direction in remove: - del self.safe_positions[direction] + del safe_positions[direction] - self.add_calculations({"function": "avoid_my_body", "my_body": self.my_body, "safe_positions": self.safe_positions}) + if add_to_calculations: + self.add_calculations({"function": "avoid_my_body", "my_body": my_body, "safe_positions": safe_positions}) - def avoid_walls(self): + return safe_positions + + def avoid_walls(self, safe_positions:dict[str, dict], add_to_calculations:bool=False): remove = [] - for direction, location in list(self.safe_positions.items()): + for direction, location in list(safe_positions.items()): 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] + del safe_positions[direction] - self.add_calculations({"function": "avoid_walls", "board_width": self.board_width, "board_height": self.board_height, "safe_positions": self.safe_positions}) + if add_to_calculations: + self.add_calculations({"function": "avoid_walls", "board_width": self.board_width, "board_height": self.board_height, "safe_positions": safe_positions}) - def avoid_snakes(self): + return safe_positions + + def avoid_snakes(self, other_snakes:list[dict], safe_positions:dict[str, dict], add_to_calculations:bool=False): remove = [] - for snake in self.other_snakes: - for direction, location in self.safe_positions.items(): + for snake in other_snakes: + for direction, location in safe_positions.items(): #if self.game_type == "constrictor": if location in snake["body"]: remove.append(direction) @@ -115,18 +121,21 @@ class TemplateSnake: remove = set(remove) for direction in remove: - del self.safe_positions[direction] + del safe_positions[direction] - self.add_calculations({"function": "avoid_snakes", "other_snakes": self.other_snakes, "safe_positions": self.safe_positions}) + if add_to_calculations: + self.add_calculations({"function": "avoid_snakes", "other_snakes": other_snakes, "safe_positions": safe_positions}) - def avoid_get_eaten_by_other_snakes(self): + return safe_positions + + def avoid_get_eaten_by_other_snakes(self, other_snakes:list[dict], safe_positions:dict[str, dict], add_to_calculations:bool=False): remove = [] no_way_out = {} self.other_snake_posible_moves = [] - for snake in self.other_snakes: - for direction, location in self.safe_positions.items(): - if len(self.safe_positions) > 1: + for snake in other_snakes: + for direction, location in safe_positions.items(): + if len(safe_positions) > 1: self.other_snake_posible_moves = [{"x": v["x"], "y": v["y"]} for k, v in self.get_possible_moves(snake["head"]).items()] if snake["length"] < self.my_snake["length"] and location in self.other_snake_posible_moves: self.eat_the_snake_overwrite = True @@ -140,21 +149,26 @@ class TemplateSnake: remove = set(remove) for direction in remove: - del self.safe_positions[direction] + del safe_positions[direction] - if len(self.safe_positions) == 0: - self.safe_positions = no_way_out + if len(safe_positions) == 0: + safe_positions = no_way_out - self.add_calculations({"function": "avoid_get_eaten_by_other_snakes", "other_snakes": self.other_snakes, "safe_positions": self.safe_positions}) + if add_to_calculations: + self.add_calculations({"function": "avoid_get_eaten_by_other_snakes", "other_snakes": other_snakes, "safe_positions": safe_positions}) - def find_safe_positions(self): - self.safe_positions = self.get_possible_moves(self.my_head) - self.add_calculations({"function": "get_possible_moves", "safe_positions": self.safe_positions}) + return safe_positions - self.avoid_my_body() - self.avoid_walls() - self.avoid_snakes() - self.avoid_get_eaten_by_other_snakes() + def find_safe_positions(self, add_to_calculations:bool=False): + safe_positions = self.get_possible_moves(self.my_head) + if add_to_calculations: + self.add_calculations({"function": "get_possible_moves", "safe_positions": safe_positions}) + + safe_positions = self.avoid_my_body(self.my_body, safe_positions, add_to_calculations) + safe_positions = self.avoid_walls(safe_positions, add_to_calculations) + safe_positions = self.avoid_snakes(self.other_snakes, safe_positions, add_to_calculations) + safe_positions = self.avoid_get_eaten_by_other_snakes(self.other_snakes, safe_positions, add_to_calculations) + return safe_positions def calculate_new_body_position(self, move:str=None, with_tail:bool=False): if move: