diff --git a/agent.py b/agent.py index c34ddcc..1d3ed08 100644 --- a/agent.py +++ b/agent.py @@ -9,7 +9,6 @@ class Agent: self.image= pygame.image.load(image_path) self.image = pygame.transform.scale(self.image, (grid_size, grid_size)) - def draw(self, screen, grid_size): # Obróć obrazek zgodnie z kierunkiem if self.direction == 'E': @@ -56,6 +55,7 @@ class Agent: elif action == 'Turn Right': self.direction = {'N': 'E', 'E': 'S', 'S': 'W', 'W': 'N'}[self.direction] + self.istate = (self.x, self.y, self.direction) feed_animal(self, animals) def feed_animal(self, animals): diff --git a/enclosure.py b/enclosure.py index 2a79c52..4541082 100644 --- a/enclosure.py +++ b/enclosure.py @@ -23,57 +23,13 @@ class Enclosure: pygame.draw.rect(screen, (0, 0, 0), rect) # Fill the area with screen.blit(self.imageGate, (gate_x * grid_size, gate_y * grid_size)) - def gateopen(self, blocked): - gate_x, gate_y = self.gate - gate_x -= 1 - gate_y -= 1 - if (gate_x, gate_y) in blocked: - blocked.remove((gate_x, gate_y)) - - - - def draw(self,screen, grid_size , blocked_fields): + def draw(self,screen, grid_size): self.imageH = pygame.transform.scale(self.imageH, (grid_size, grid_size)) self.imageV = pygame.transform.scale(self.imageV, (grid_size, grid_size)) if self.x1 < self.x2: for i in range(self.x1, self.x2+1): screen.blit(self.imageH, (i * grid_size, self.y1 * grid_size)) - blocked_fields.add((i, self.y1)) screen.blit(self.imageH, (i * grid_size, self.y2 * grid_size)) - blocked_fields.add((i, self.y2)) - if self.y1 < self.y2: - for j in range(self.y1, self.y2+1): - screen.blit(self.imageH, (self.x1 * grid_size, j * grid_size)) - blocked_fields.add((self.x1, j)) - screen.blit(self.imageH, (self.x2 * grid_size, j * grid_size)) - blocked_fields.add((self.x2, j)) - if self.y1 > self.y2: - for j in range(self.y2, self.y1+1): - screen.blit(self.imageH, (self.x1 * grid_size, j * grid_size)) - blocked_fields.add((self.x1, j)) - screen.blit(self.imageH, (self.x2 * grid_size, j * grid_size)) - blocked_fields.add((self.x2, j)) - if self.x1 > self.x2: - for i in range(self.x2, self.x1+1): - screen.blit(self.imageH, (i * grid_size, self.y1 * grid_size)) - blocked_fields.add((i, self.y1)) - screen.blit(self.imageH, (i * grid_size, self.y2 * grid_size)) - blocked_fields.add((i, self.y2)) - if self.y1 < self.y2: - for j in range(self.y1, self.y2+1): - screen.blit(self.imageH, (self.x1 * grid_size, j * grid_size)) - blocked_fields.add((self.x1, j)) - screen.blit(self.imageH, (self.x2 * grid_size, j * grid_size)) - blocked_fields.add((self.x2, j)) - if self.y1 > self.y2: - for j in range(self.y2, self.y1+1): - screen.blit(self.imageH, (self.x1 * grid_size, j * grid_size)) - blocked_fields.add((self.x1, j)) - screen.blit(self.imageH, (self.x2 * grid_size, j * grid_size)) - blocked_fields.add((self.x2, j)) - - - - - - + for j in range(self.y1, self.y2+1): + screen.blit(self.imageV, (self.x1 * grid_size, j * grid_size)) + screen.blit(self.imageV, (self.x2 * grid_size, j * grid_size)) \ No newline at end of file diff --git a/images/agent.png b/images/agent.png deleted file mode 100644 index 1bc4be8..0000000 Binary files a/images/agent.png and /dev/null differ diff --git a/images/fenceVer.png b/images/fenceVer.png index 2699618..b86e9b6 100644 Binary files a/images/fenceVer.png and b/images/fenceVer.png differ diff --git a/main.py b/main.py index 68fe5d4..3ba80ec 100644 --- a/main.py +++ b/main.py @@ -31,31 +31,48 @@ fenceH = pygame.image.load('images/fenceHor.png') fenceV = pygame.image.load('images/fenceVer.png') gate = pygame.image.load('images/gate.png') - -fences = set() +obstacles = set() animals_position = set() +# region Define the animals +giraffe1 = Giraffe(0, 0, adult=True) +giraffe2 = Giraffe(0, 0, adult=True) +giraffe3 = Giraffe(0, 0, adult=True) +giraffe4 = Giraffe(0, 0) +giraffe5 = Giraffe(0, 0) +bear1 = Bear(0, 0, adult=True) +bear2 = Bear(0, 0, adult=True) +bear3 = Bear(0, 0) +bear4 = Bear(0, 0) +bear5 = Bear(0, 0) +penguin1 = Penguin(0, 0) +penguin2 = Penguin(0, 0) +penguin3 = Penguin(0, 0) +penguin4 = Penguin(0, 0) +elephant1 = Elephant(0, 0, adult=True) +elephant2 = Elephant(0, 0, adult=True) +elephant3 = Elephant(0, 0) +elephant4 = Elephant(0, 0) +elephant5 = Elephant(0, 0) +parrot1 = Parrot(0, 0) +parrot2 = Parrot(0, 0) +parrot3 = Parrot(0, 0) +parrot4 = Parrot(0, 0) +parrot5 = Parrot(0, 0) +Animals = [giraffe1, giraffe2, giraffe3, giraffe4, giraffe5, bear1, bear2, bear3, bear4, bear5, elephant1, elephant2, elephant3, elephant4, elephant5, penguin1, penguin2, penguin3, penguin4, parrot1, parrot2, parrot3, parrot4, parrot5] +# endregion -an1 = Parrot(16, 2) -an2 = Penguin(8, 6) -an3 = Bear(14, 9) -old_an2 = Giraffe(18,4, adult=True) -old_an1 = Elephant(4, 7, adult=True) -an4 = Elephant(4,3) - -Animals = [an1, an2, an3, an4, old_an1, old_an2] - +# region Define Enclosures # Enclosure (lewy_górny_x, lewy_górny_y, prawy_dolny_x, prawy_dolny_y, brama, klimat, fenceH, fenceV, gate_obrazek) -en1 = Enclosure(1,5, 9,11, (9,6),"medium", fenceH, fenceV, gate) -en2 = Enclosure(13,1, 29,3, (16,3), 'medium', fenceH, fenceV, gate) -en3 = Enclosure(11,5, 16,11, (12,5),'cold', fenceH, fenceV, gate) -en4 = Enclosure(19,5, 30,11, (25,5),'hot', fenceH, fenceV, gate) -en5 = Enclosure(4,13, 28,15, (16,13),'cold', fenceH, fenceV, gate) - +en1 = Enclosure(0,5, 9,11, (9,6),"hot", fenceH, fenceV, gate) # Lewa klatka +en2 = Enclosure(13,0, 29,3, (16,3), 'medium', fenceH, fenceV, gate) # Górna klatka +en3 = Enclosure(11,5, 16,11, (12,5),'cold', fenceH, fenceV, gate) # Środkowa klatka +en4 = Enclosure(19,5, 31,11, (25,5),'hot', fenceH, fenceV, gate) # Prawa klatka +en5 = Enclosure(4,13, 28,16, (16,13),'cold', fenceH, fenceV, gate) # Dolna klatka Enclosures = [en1, en2, en3, en4, en5] - +# endregion def draw_grid(): for y in range(0, GRID_HEIGHT * GRID_SIZE, GRID_SIZE): @@ -65,16 +82,12 @@ def draw_grid(): def draw_enclosures(): for enclosure in Enclosures: - enclosure.draw(screen, GRID_SIZE, fences) + enclosure.draw(screen, GRID_SIZE) def draw_gates(): for enclosure in Enclosures: enclosure.gatebuild(screen, GRID_SIZE) -def opengates(): - for enclosure in Enclosures: - enclosure.gateopen(fences) - def draw_Animals(): for Animal in Animals: Animal.draw(screen, GRID_SIZE) @@ -86,10 +99,10 @@ def draw_Animals(): def spawn_all_animals(): for Animal in Animals: spawner1 = Spawner(Animal, Enclosures) - spawner1.spawn_animal(fences, animals_position) + spawner1.spawn_animal(obstacles, animals_position) +obstacles = set() def generate_obstacles(): - obstacles = [] for en in Enclosures: # Pobierz współrzędne bramy @@ -100,60 +113,70 @@ def generate_obstacles(): # Dodaj lewy brzeg prostokąta for y in range(en.y1, en.y2 + 1): if (en.x1, y) != (gate_x, gate_y): - obstacles.append((en.x1, y)) + obstacles.add((en.x1, y)) # Dodaj prawy brzeg prostokąta for y in range(en.y1, en.y2 + 1): if (en.x2, y) != (gate_x, gate_y): - obstacles.append((en.x2, y)) + obstacles.add((en.x2, y)) # Dodaj górny brzeg prostokąta for x in range(en.x1+1, en.x2): if (x, en.y1) != (gate_x, gate_y): - obstacles.append((x, en.y1)) + obstacles.add((x, en.y1)) # Dodaj dolny brzeg prostokąta for x in range(en.x1+1, en.x2): if (x, en.y2) != (gate_x, gate_y): - obstacles.append((x, en.y2)) + obstacles.add((x, en.y2)) return obstacles -# region Obstacles Tests -# WHITE = (255,255,255) -# TRANSPARENT_BLACK = (0, 0, 0, 128) # Półprzezroczysty czarny -# def draw_obstacles(obstacles): -# for obstacle in obstacles: -# x, y = obstacle -# pygame.draw.rect(screen, TRANSPARENT_BLACK, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE)) +available_fields_small = set() +available_fields_large = set() +def generate_available_fields(): + for enclosure in Enclosures: + for x in range(enclosure.x1 + 1, enclosure.x2): + for y in range(enclosure.y1 + 1, enclosure.y2): + field = (x, y) + if field not in obstacles: + available_fields_small.add(field) + if x < enclosure.x2 - 1 and y < enclosure.y2 - 1: + available_fields_large.add(field) -# def main(): -# obstacles = generate_obstacles() # Załóżmy, że masz funkcję generate_obstacles, która generuje listę przeszkód +# region Fields Tests +WHITE = (255,255,255) +GREEN = (0, 255, 0) +YELLOW = (255, 255, 0) +BLACK = (0, 0, 0) -# # Pętla główna -# running = True -# while running: -# # Obsługa zdarzeń -# for event in pygame.event.get(): -# if event.type == pygame.QUIT: -# running = False +def draw_fields(fields, color): + for field in fields: + x, y = field + pygame.draw.rect(screen, color, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE)) -# # Czyszczenie ekranu -# screen.fill(WHITE) +def main_fields_tests(): + obstacles = generate_obstacles() -# # Rysowanie przeszkód -# draw_obstacles(obstacles) -# # Odświeżenie ekranu -# pygame.display.flip() + while True: + screen.fill(WHITE) -# # Wyjście z Pygame -# pygame.quit() + draw_grid() + draw_fields(obstacles, BLACK) + generate_available_fields() + + draw_fields(available_fields_small, GREEN) + draw_fields(available_fields_large, YELLOW) + + # Odświeżenie ekranu + pygame.display.flip() # endregion +# region Main Code def main(): - initial_state = (1,1,'W') + initial_state = (0,0,'S') agent = Agent(initial_state, 'images/agent1.png', GRID_SIZE) obstacles = generate_obstacles() @@ -163,6 +186,7 @@ def main(): spawned = False while True: + # Manualne poruszanie agentem for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() @@ -175,25 +199,27 @@ def main(): draw_gates() if not spawned: spawn_all_animals() - - # region Test szukania ścieżki for animal in Animals: animal._feed = 2 # Ustawienie aby zwierzę było głodne - animal = random.choice(Animals) - # actions = graphsearch(agent.istate, (animal.x, animal.y), GRID_WIDTH, GRID_HEIGHT, obstacles) - # endregion - spawned = True draw_Animals() - opengates() agent.draw(screen, GRID_SIZE) pygame.display.flip() clock.tick(10) - + if actions: action = actions.pop(0) agent.move(action, GRID_WIDTH, GRID_HEIGHT, obstacles, Animals) pygame.time.wait(200) - + else: + animal = random.choice(Animals) + actions = graphsearch(agent.istate, (animal.x, animal.y), GRID_WIDTH, GRID_HEIGHT, obstacles) +# endregion + if __name__ == "__main__": - main() \ No newline at end of file + debug_mode = False # Jeśli True to pokazuje dostępne pola + + if debug_mode: + main_fields_tests() + else: + main() diff --git a/spawner.py b/spawner.py index 181ea06..9d09380 100644 --- a/spawner.py +++ b/spawner.py @@ -1,44 +1,42 @@ import random - class Spawner: def __init__(self, animal, enclosures): self.animal = animal - self.enclosures = enclosures + # Wyrażenie listowe filtrujące tylko te wybiegi, które pasują do środowiska zwierzęcia + self.enclosures = [enclosure for enclosure in enclosures if enclosure.type == self.animal.environment] def spawn_animal(self, blocked, taken): - possibilities = self.enclosures - fitting = [] - for option in possibilities: - if option.type == self.animal.environment: - fitting.append(option) - enclosure = random.choice(fitting) + enclosure = random.choice(self.enclosures) + while True: - if enclosure.x1 < enclosure.x2: - self.animal.x = random.randint(enclosure.x1, enclosure.x2) - if enclosure.y1 < enclosure.y2: - self.animal.y = random.randint(enclosure.y1, enclosure.y2) - if enclosure.y1 > enclosure.y2: - self.animal.y = random.randint(enclosure.y2, enclosure.y1) - if enclosure.x1 > enclosure.x2: - self.animal.x = random.randint(enclosure.x2, enclosure.x1) - if enclosure.y1 < enclosure.y2: - self.animal.y = random.randint(enclosure.y1, enclosure.y2) - if enclosure.y1 > enclosure.y2: - self.animal.y = random.randint(enclosure.y2, enclosure.y1) + if self.animal.adult: + self.animal.x = random.randint(enclosure.x1+1, enclosure.x2-2) + self.animal.y = random.randint(enclosure.y1+1, enclosure.y2-2) + else: + self.animal.x = random.randint(enclosure.x1+1, enclosure.x2) + self.animal.y = random.randint(enclosure.y1+1, enclosure.y2) + if self.check(blocked, taken): break def check(self, blocked, taken): x = self.animal.x y = self.animal.y + if (x,y) in blocked or (x,y) in taken: return False - taken.add((x,y)) - return True - - - + if self.animal.adult: + + adult_fields = [(x, y), (x+1,y), (x,y+1), (x+1,y+1)] # Duże zwierze zajmuje 4 pola + if any(field in taken for field in adult_fields): # Jeśli stawiane zwierze jest dorosłe i jakiekolwiek pole jest zajęte, to nie można postawić zwierzęcia + return False + + for field in adult_fields: # Dodaj wszystkie pola zajęte przez duże zwierzę + taken.add(field) + else: + taken.add((x,y)) + return True \ No newline at end of file