Closed Jxshyz closed 7 months ago
hi, I tried around and thought of something like this:
def search_food(self, board):
visibilityrange = self.genetic["Visibilityrange"]
#creates a mesh grid for coords within the cisibility range
dx, dy = np.meshgrid(range(-visibilityrange, visibilityrange + 1), range(-visibilityrange, visibilityrange + 1))
# finds the index of the minimum distance
min_distance = np.argmin(distances)
# calculates the difference (or "offset") in x and y based on the FLATTENED min_distance index
num_cols = distances.shape[1]
diff_x = min_distance // num_cols
diff_y = min_distance % num_cols
#this calculates the nearest food, transforms the relative position to the absolute placement on the board
x, y = self.position[0] + diff_x, self.position[1] + diff_y
if 0 <= x < WIDTH and 0 <= y < HEIGHT and board.food[x][y] != 0:
#here just as before....
return None
and for the move function:
if self_sick is True:
[#code as before]
else:
#get the relative position of the nearest food to the agent (as returned in the previous def"search_food")
relative_food_pos = self.search_food(board)
#and then if food is within visibility range do this
if relative_food_pos is not None:
dx, dy = relative_food_pos
new_x = max(0, min(WIDTH - 1, self.position[0] + dx))
new_y = max(0, min(HEIGHT - 1, self.position[1] + dy))
self.position = (new_x, new_y)
self.covered_distance += 1
else:
#do a random move
What do you think?
Thats a really good idea to use more efficient data structures for this heavy method.
What do you think about my following shot on calculating the distances: def search_food_efficient(self, board): visibilityrange = self.genetic["Visibilityrange"]
# Erstelle ein Gitter (Grid) aller Punkte innerhalb der Sichtbarkeitsreichweite
y_range, x_range = np.ogrid[-visibilityrange:visibilityrange+1, -visibilityrange:visibilityrange+1]
# Berechne die Distanz von jedem Punkt im Gitter zur aktuellen Position des Agenten
distances = np.sqrt(x_range**2 + y_range**2)
# Erstelle ein Boolesches Gitter, das True ist, wo Nahrung vorhanden ist
food_mask = np.zeros_like(distances, dtype=bool)
# Prüfe, welche Punkte innerhalb der Grenzen liegen und wo Nahrung ist
for dy in range(-visibilityrange, visibilityrange + 1):
for dx in range(-visibilityrange, visibilityrange + 1):
x, y = self.position[0] + dx, self.position[1] + dy
if 0 <= x < WIDTH and 0 <= y < HEIGHT and board.food[x][y] != 0:
food_mask[dy + visibilityrange, dx + visibilityrange] = True
# Wende die Nahrungsmaske auf die Distanzen an, setze alle anderen auf unendlich
distances = np.where(food_mask, distances, np.inf)
# Finde die Position der minimalen Distanz
min_distance_idx = np.argmin(distances)
if distances.flat[min_distance_idx] == np.inf:
return None # Keine Nahrung gefunden
# Berechne die relative Position der nächstgelegenen Nahrungsquelle
dy, dx = np.unravel_index(min_distance_idx, distances.shape)
closest_food = (dx - visibilityrange, dy - visibilityrange)
return closest_food
also i figured that agents might infinitely circle around food - what do you think about my attempt on stopping this:
relative_food_pos = self.search_food_efficient(board) if relative_food_pos is not None: dx, dy = relative_food_pos
step_size = self.genetic["Kondition"] # Angenommen, dies bestimmt die maximale Bewegungsdistanz
# Adjust movement to ensure the agent stops at the food
dx = max(min(dx, step_size), -step_size) if dx != 0 else 0 # Makes sure that step size adjusts to the agent - food distance
dy = max(min(dy, step_size), -step_size) if dy != 0 else 0
new_x = max(0, min(WIDTH - 1, self.position[0] + dx))
new_y = max(0, min(HEIGHT - 1, self.position[1] + dy))
self.position = (new_x, new_y)
self.covered_distance += 1
# Überprüfe, ob die neue Position Nahrung enthält und konsumiere diese
if board.food[new_x][new_y] != 0:
self.consuming_food(board.food[new_x][new_y])
board.food[new_x][new_y] = 0 # Entferne die Nahrung von der Karte
else:
# Führe einen zufälligen Zug aus, wenn keine Nahrung gefunden wird
dx = random.choice([-1, 1]) * step_size
dy = random.choice([-1, 1]) * step_size
new_x = max(0, min(WIDTH - 1, self.position[0] + dx))
new_y = max(0, min(HEIGHT - 1, self.position[1] + dy))
self.position = (new_x, new_y)
self.covered_distance += 1
implemented it
At the moment we use a double for loop to search the whole board for food. Instead, we could use np.argmin to store the distance between the agent and the food and use the respective visibility as a trigger so that the agent recognizes the food and moves towards it.