remove not used function is_food_nearby
This commit is contained in:
@@ -1,165 +0,0 @@
|
||||
from snakes.TemplateSnake import TemplateSnake
|
||||
|
||||
from queue import PriorityQueue, Queue
|
||||
import random
|
||||
|
||||
class AStarSnake(TemplateSnake):
|
||||
def avoid_my_body(self, my_body, possible_moves: dict) -> list:
|
||||
"""
|
||||
my_body: Set of tuples representing x/y coordinates for every segment of a Battlesnake.
|
||||
e.g. {(0, 0), (1, 0), (2, 0)}
|
||||
possible_moves: Dictionary of moves to pick from, with coordinates as tuples.
|
||||
e.g. {"up": (0, 1), "down": (0, -1), "left": (-1, 0), "right": (1, 0)}
|
||||
|
||||
return: The dictionary of remaining possible_moves, with the moves leading to self-collision removed
|
||||
"""
|
||||
remove = []
|
||||
for direction, location in possible_moves.items():
|
||||
if location in my_body:
|
||||
remove.append(direction)
|
||||
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
|
||||
return possible_moves
|
||||
|
||||
def avoid_walls(self, board_width: int, board_height: int, possible_moves: dict):
|
||||
remove = []
|
||||
for direction, location in possible_moves.items():
|
||||
x_out_range = (location[0] < 0 or location[0] == board_width)
|
||||
y_out_range = (location[1] < 0 or location[1] == board_height)
|
||||
if x_out_range or y_out_range:
|
||||
remove.append(direction)
|
||||
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
|
||||
return possible_moves
|
||||
|
||||
def avoid_snakes(self, snakes: list, possible_moves: dict):
|
||||
remove = []
|
||||
for snake in snakes:
|
||||
for direction, location in possible_moves.items():
|
||||
if location in snake["body"]:
|
||||
remove.append(direction)
|
||||
|
||||
remove = set(remove)
|
||||
for direction in remove:
|
||||
del possible_moves[direction]
|
||||
|
||||
return possible_moves
|
||||
|
||||
def get_target_close(self, foods: list, my_head: tuple):
|
||||
if len(foods) == 0:
|
||||
return None
|
||||
return min(foods, key=lambda food: abs(food["x"] - my_head[0]) + abs(food["y"] - my_head[1]))
|
||||
|
||||
def flood_fill(self, board_width: int, board_height: int, my_body: set):
|
||||
"""
|
||||
Perform Flood Fill to identify safe areas on the board.
|
||||
"""
|
||||
visited = set()
|
||||
safe_cells = set()
|
||||
|
||||
# Define directions (up, down, left, right)
|
||||
directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
|
||||
|
||||
# Perform Flood Fill from each cell not occupied by the snake's body
|
||||
for x in range(board_width):
|
||||
for y in range(board_height):
|
||||
if (x, y) not in my_body and (x, y) not in visited:
|
||||
# Start Flood Fill from this cell
|
||||
q = Queue()
|
||||
q.put((x, y))
|
||||
visited.add((x, y))
|
||||
safe_cells.add((x, y))
|
||||
|
||||
# Continue Flood Fill until the queue is empty
|
||||
while not q.empty():
|
||||
current_cell = q.get()
|
||||
for dx, dy in directions:
|
||||
new_cell = (current_cell[0] + dx, current_cell[1] + dy)
|
||||
if 0 <= new_cell[0] < board_width and 0 <= new_cell[1] < board_height:
|
||||
if new_cell not in my_body and new_cell not in visited:
|
||||
q.put(new_cell)
|
||||
visited.add(new_cell)
|
||||
safe_cells.add(new_cell)
|
||||
|
||||
return safe_cells
|
||||
|
||||
def choose_move(self, data: dict) -> str:
|
||||
my_head = (data["you"]["head"]["x"], data["you"]["head"]["y"])
|
||||
my_body = {(part["x"], part["y"]) for part in data["you"]["body"]}
|
||||
board_height = data["board"]["height"]
|
||||
board_width = data["board"]["width"]
|
||||
foods = data["board"]["food"]
|
||||
|
||||
# Perform Flood Fill to identify safe areas on the board
|
||||
safe_cells = self.flood_fill(board_width, board_height, my_body)
|
||||
|
||||
# Find the nearest food located in a safe area using A* algorithm
|
||||
def heuristic(a, b):
|
||||
return abs(a[0] - b[0]) + abs(a[1] - b[1])
|
||||
|
||||
def a_star(start, goal:set=()):
|
||||
open_set = Queue()
|
||||
open_set.put(start)
|
||||
came_from = {}
|
||||
g_score = {start: 0}
|
||||
|
||||
while not open_set.empty():
|
||||
current = open_set.get()
|
||||
|
||||
if current == goal:
|
||||
path = []
|
||||
while current in came_from:
|
||||
path.append(current)
|
||||
current = came_from[current]
|
||||
return path[::-1][0]
|
||||
|
||||
for dx, dy in [(0, 1), (0, -1), (-1, 0), (1, 0)]:
|
||||
new_cell = (current[0] + dx, current[1] + dy)
|
||||
if new_cell in safe_cells:
|
||||
tentative_g_score = g_score[current] + 1
|
||||
if new_cell not in g_score or tentative_g_score < g_score[new_cell]:
|
||||
came_from[new_cell] = current
|
||||
g_score[new_cell] = tentative_g_score
|
||||
open_set.put(new_cell)
|
||||
|
||||
return None
|
||||
|
||||
try:
|
||||
nearest_food = min(foods, key=lambda food: heuristic(my_head, (food["x"], food["y"])))
|
||||
target_position = (nearest_food["x"], nearest_food["y"])
|
||||
move_target = a_star(my_head, target_position)
|
||||
except ValueError:
|
||||
# TODO: What to do when no food is available?
|
||||
# - Avoid own body and other snakes
|
||||
# - Flut fill?
|
||||
move_target = a_star(my_head, safe_cells)
|
||||
print(move_target)
|
||||
|
||||
# Choose the next move based on the path obtained from A* algorithm
|
||||
if move_target:
|
||||
dx = move_target[0] - my_head[0]
|
||||
dy = move_target[1] - my_head[1]
|
||||
|
||||
self.add_to_history({"my_head": my_head, "my_body": tuple(my_body), "target": move_target, "target_position": target_position, "nearest_food": nearest_food, "dx": dx, "dy": dy})
|
||||
if dx == 1:
|
||||
return "right"
|
||||
elif dx == -1:
|
||||
return "left"
|
||||
elif dy == 1:
|
||||
return "up"
|
||||
elif dy == -1:
|
||||
return "down"
|
||||
|
||||
# If no safe path to food is found, choose a random move
|
||||
random_move = random.choice(["up", "down", "left", "right"])
|
||||
|
||||
try:
|
||||
self.add_to_history({"my_head": my_head, "my_body": tuple(my_body), "target": move_target, "target_position": target_position, "nearest_food": nearest_food, "random_move": random_move})
|
||||
except UnboundLocalError:
|
||||
self.add_to_history({"my_head": my_head, "my_body": tuple(my_body), "target": move_target, "random_move": random_move})
|
||||
|
||||
return random_move
|
||||
@@ -5,7 +5,6 @@ class BetterMasterSnake(TemplateSnake):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.name = "BetterMasterSnake"
|
||||
self.disabled_check_if_food_is_near_by = True
|
||||
# Definiere die möglichen Bewegungsrichtungen
|
||||
self.min_safe_area = 2
|
||||
|
||||
@@ -128,7 +127,7 @@ class BetterMasterSnake(TemplateSnake):
|
||||
|
||||
self.find_safe_positions()
|
||||
if self.eat_the_snake_overwrite:
|
||||
move = self.overwrite_eat_the_other_snake(move, game_data["turn"])
|
||||
return self.overwrite_eat_the_other_snake(move, game_data["turn"])
|
||||
|
||||
if self.game_type == "constrictor":
|
||||
move = self.selected_move_constrictor()
|
||||
@@ -155,13 +154,12 @@ class BetterMasterSnake(TemplateSnake):
|
||||
self.add_calculations({"function": "find_direction", "my_head": self.my_head, "move": move})
|
||||
return move
|
||||
|
||||
def selected_move_standard(self):
|
||||
def selected_move_standard(self, move=None):
|
||||
# Finde den besten Weg zur Nahrung
|
||||
if self.is_food_nearby() or self.disabled_check_if_food_is_near_by:
|
||||
path_to_food = self.find_path_to_food()
|
||||
if path_to_food:
|
||||
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})
|
||||
path_to_food = self.find_path_to_food()
|
||||
if path_to_food:
|
||||
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()
|
||||
@@ -172,15 +170,6 @@ class BetterMasterSnake(TemplateSnake):
|
||||
self.add_calculations({"function": "ensure_escape_route", "my_head": self.my_head, "move": move, "safe_positions": self.safe_positions})
|
||||
return move
|
||||
|
||||
def is_food_nearby(self):
|
||||
for food in self.food_positions:
|
||||
if abs(self.my_head['x'] - food['x']) <= 1 and abs(self.my_head['y'] - food['y']) <= 1:
|
||||
self.add_calculations({"function": "is_food_nearby", "my_head": self.my_head, "food": food, "return": True})
|
||||
return True
|
||||
|
||||
self.add_calculations({"function": "is_food_nearby", "my_head": self.my_head, "food_positions": self.food_positions, "return": False})
|
||||
return False
|
||||
|
||||
def find_path_to_food(self):
|
||||
# Exclude own snake's body from obstacles
|
||||
obstacles = set((part['x'], part['y']) for part in self.my_body)
|
||||
|
||||
Reference in New Issue
Block a user