From 86c5ad6fd192dff8bc86584e5d937e75a7ef124b Mon Sep 17 00:00:00 2001 From: 473575 Date: Mon, 15 May 2023 10:58:18 +0200 Subject: [PATCH] Orientacja i A* --- res/map.txt | 24 +++---- res/tiles.png | Bin 14735 -> 16614 bytes src/agent.py | 165 +++++++++++++++++++++++++++++++++++++++++++--- src/simulation.py | 65 ++++++++++++++---- 4 files changed, 220 insertions(+), 34 deletions(-) diff --git a/res/map.txt b/res/map.txt index 375db8b..70e9291 100644 --- a/res/map.txt +++ b/res/map.txt @@ -1,14 +1,14 @@ MP--H--------------------- -ORRRRRRRRRRRRRRRRRR---R--- -SZ--R------R------R---RRR- -----R------R------R---R--- --RRRR------RRRRRRRRRRRR--- --R--R-------------R------- --R--RRRRRRRRRRRRRRRH------ --R--R---R---RH----R------- --R--R---R---RH----RRRRRRR- --R--R-------H-----R------- --R--R-----R----R--R------- --R--R-----R----R--R------- --RRRRRRRRRRRRRRRRRRRRRRR-- +RRRRRRRRRRRRRRRRRRR---G--- +SZ--R------G------R---GGG- +----R------G------R---G--- +-RRRR------GGGGGGGRRRRR--- +-R--G-------------R------- +-R--GGGGGGGGGGGGGGRH------ +-R--G---G---GH----R------- +-R--G---G---GH----RRRRRRR- +-R--G-------H-----R------- +-R--G-----G----G--R------- +-R--G-----G----G--R------- +-RRRRRRRRRRRRRRRRRRRORRR-- -------------------------- \ No newline at end of file diff --git a/res/tiles.png b/res/tiles.png index c5f4674a4c52af1620d4778d258c30fdc4802fc1..d53553b88b2f73a1f31ef00916da55fa8ee0d1ad 100644 GIT binary patch delta 7036 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 delta 5144 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 diff --git a/src/agent.py b/src/agent.py index 60f0fa8..217d346 100644 --- a/src/agent.py +++ b/src/agent.py @@ -1,5 +1,6 @@ -from random import randint +import random import pygame as pg +import heapq def vector_to_tuple(vector): @@ -23,20 +24,37 @@ class Agent: self.houses = {} self.dumps = {} self.fullness = None + self.weights = {} + self.orientation = 90 + # utworzenie grafu dróg - roads_pos = [vector_to_tuple(pos) for pos in self.simulation.state.roads_pos] + roads_pos = [vector_to_tuple(pos) for pos in self.simulation.state.road_pos_g + self.simulation.state.road_pos_r] + roads_pos.sort() for index, pos in enumerate(roads_pos): + if pos[0] < 0 or pos[0] >= 27 or pos[1] < 0 or pos[1] >= 14: + continue for another_pos in roads_pos[index:]: - if pos == another_pos: + if pos == another_pos or another_pos[0] < 0 or another_pos[0] >= 27 or another_pos[1] < 0 or another_pos[1] >= 14: continue - if abs(pos[0] - another_pos[0]) <= 1 and abs(pos[1] - another_pos[1]) <= 1: + if ((abs(pos[0] - another_pos[0]) == 1 and abs(pos[1] - another_pos[1]) == 0) or (abs(pos[0] - another_pos[0]) == 0 and abs(pos[1] - another_pos[1]) == 1)): if pos not in self.graph.keys(): self.graph[pos] = set() if another_pos not in self.graph.keys(): self.graph[another_pos] = set() + if another_pos in self.simulation.state.road_pos_r: + weight = 2 + elif another_pos in self.simulation.state.road_pos_g: + weight = 3 + else: + weight = 1 self.graph[pos].add(another_pos) self.graph[another_pos].add(pos) + self.weights[(pos,another_pos)] = weight + self.weights[(another_pos, pos)] = weight + + + # dołączenie domów i składowisk do grafu dróg entities = self.simulation.state.entities @@ -46,15 +64,23 @@ class Agent: (entity_pos[0]+1, entity_pos[1]), (entity_pos[0], entity_pos[1]-1), (entity_pos[0], entity_pos[1]+1)]: + if neighbour_pos[0] < 0 or neighbour_pos[0] >= 27 or neighbour_pos[1] < 0 or neighbour_pos[1] >= 14: + continue if neighbour_pos in roads_pos: if entity_pos not in self.graph.keys(): self.graph[entity_pos] = set() self.graph[entity_pos].add(neighbour_pos) self.graph[neighbour_pos].add(entity_pos) + self.weights[(entity_pos, neighbour_pos)] = 1 + self.weights[(neighbour_pos, entity_pos)] = 1 if entity.entity_type == 'dump': self.dumps[entity.trash_type] = vector_to_tuple(entity.position) if entity.entity_type == 'house': self.houses[vector_to_tuple(entity.position)] = HousePOI() + + self.path = self.A_star() + + def update(self): entities = self.simulation.state.entities @@ -62,13 +88,136 @@ class Agent: if entity.entity_type == 'truck': self.current_pos = vector_to_tuple(entity.position) self.fullness = entity.fullness + self.orientation = entity.orientation + def decide_move(self): - possible_positions = self.graph[self.current_pos] - possible_moves = [pg.Vector2(pos[0] - self.current_pos[0], pos[1] - self.current_pos[1]) for pos in possible_positions] + + + + move = self.path.pop + + if self.orientation == 0: + if move[0] != 0: + if move[0] == 1: + return 90 + else: + return 270 + elif move[1] != 0: + if move[1] == 1: + return pg.Vector2(move) + else: + return 180 + elif self.orientation == 90: + if move[0] != 0: + if move[0] == 1: + return pg.Vector2(move) + else: + return 270 + elif move[1] != 0: + if move[1] == 1: + return 0 + else: + return 180 + elif self.orientation == 180: + if move[0] != 0: + if move[0] == 1: + return 90 + else: + return 270 + elif move[1] != 0: + if move[1] == 1: + return 0 + else: + return pg.Vector2(move) + else: + if move[0] != 0: + if move[0] == 1: + return 90 + else: + return pg.Vector2(move) + elif move[1] != 0: + if move[1] == 0: + return 0 + else: + return 180 + + def heuristic(self, start_pos, end_pos): + return abs((end_pos[0] - start_pos[0])) + abs((end_pos[1] - start_pos[1])) + + def weight_cost(self, start_pos, end_pos): + return self.weights[(start_pos, end_pos)] + + def get_move_cost(self, start_pos, end_pos): + return self.heuristic(start_pos, end_pos) + self.weight_cost(start_pos, end_pos) + + def get_start_state(self): + entities = self.simulation.state.entities + for entity in entities: + if entity.entity_type == 'truck': + orientation = entity.orientation + position = self.current_pos + house_list = tuple(self.houses) + start_state = (position, house_list) + return start_state + + def get_end_state(self): + position = (0,1) + house_list = () + end_state = (position, house_list) + return end_state + + def succesor(self, state): + successors_pos = self.graph[state[0]] + house_list = [state[1]] + successors = () + for pos in successors_pos: + if pos in house_list: + house_list.remove(pos) + successors += ((pos, tuple(house_list)),) + else: + successors += ((pos, tuple(house_list)),) + return successors + + + def A_star(self): + fringe = [] + explored = set() + istate = self.get_start_state() + goaltest = self.get_end_state() + node = (istate, None) + + heapq.heappush(fringe, (self.heuristic(istate[0], goaltest[0]), node)) + + while fringe: + _, el = heapq.heappop(fringe) + elem = el[0] + parent = el[1] + + if elem == goaltest: + actions = [] + while parent is not None: + actions.append(elem[0]) + elem = parent + actions.reverse() + return actions + + explored.add(elem) + + for succ in self.succesor(elem): + + node = (succ, elem) + p = self.heuristic(succ[0], goaltest[0]) + + if succ not in explored and not any(tup[1][0] == succ for tup in fringe): + heapq.heappush(fringe, (p,node)) + elif any(tup[1] == succ for tup in fringe): + i = next(i for node in enumerate(fringe) if node[1][0] == succ) + if fringe[i][0] > p: + fringe[i] = (p,node) + return False + - move = possible_moves[randint(0, len(possible_moves)-1)] - return move def discover(self): if self.current_pos in self.houses.keys(): diff --git a/src/simulation.py b/src/simulation.py index 8f2375d..0d9effe 100644 --- a/src/simulation.py +++ b/src/simulation.py @@ -4,14 +4,18 @@ from random import randint import pygame as pg from agent import Agent -ROAD_SPRITE = pg.Vector2(0, 0) +ROAD_SPRITE_R = pg.Vector2(0, 0) +ROAD_SPRITE_G = pg.Vector2(0, 1) HOUSE_WITHOUT_TRASH_SPRITE = pg.Vector2(1, 0) HOUSE_WITH_TRASH_SPRITE = pg.Vector2(1, 1) HOUSE_SPRITES = {0: HOUSE_WITHOUT_TRASH_SPRITE, 1: HOUSE_WITH_TRASH_SPRITE} -TRUCK_SPRITE = pg.Vector2(2, 0) +TRUCK_SPRITE_R = pg.Vector2(2, 0) +TRUCK_SPRITE_D = pg.Vector2(2,1) +TRUCK_SPRITE_L = pg.Vector2(2,2) +TRUCK_SPRITE_U = pg.Vector2(2,3) PAPER_DUMP_SPRITE = pg.Vector2(3, 0) PLASTIC_DUMP_SPRITE = pg.Vector2(3, 1) @@ -34,18 +38,31 @@ class Entity: class TruckEntity(Entity): def __init__(self, state, position): super().__init__(state, position) - self.tile = TRUCK_SPRITE self.entity_type = 'truck' + self.tile = TRUCK_SPRITE_R self.fullness = {'paper': 0, 'glass': 0, 'plastic': 0, 'mixed': 0} + self.orientation = 90 + + def rotate_img(self, orientation): + self.orientation = orientation + if orientation == 0: + self.tile = TRUCK_SPRITE_U + elif orientation == 90: + self.tile = TRUCK_SPRITE_R + elif orientation == 180: + self.tile = TRUCK_SPRITE_D + elif orientation == 270: + self.tile = TRUCK_SPRITE_L def move(self, move_vector): proposed_pos = self.position + move_vector move_valid = True - if proposed_pos not in self.state.roads_pos \ + if proposed_pos not in self.state.road_pos_r \ + and proposed_pos not in self.state.road_pos_g \ and proposed_pos not in self.state.houses_pos \ and proposed_pos not in self.state.dumps_pos: move_valid = False @@ -86,13 +103,14 @@ class DumpEntity(Entity): class SimulationState: def __init__(self): - self.roads_pos = [] + self.road_pos_r = [] + self.road_pos_g = [] self.houses_pos = [] self.dumps_pos = [] self.entities = [] # stworzenie mapy i jednostek na podstawie pliku txt - map_path = Path("../res/map.txt") + map_path = Path(r"..\res\map.txt") with open(map_path, "r") as map_file: map_data = map_file.readlines() max_x = len(map_data[0].replace('\n', '')) @@ -103,9 +121,11 @@ class SimulationState: if tile == "O": self.truck_origin = pg.Vector2(x, y) - self.roads_pos.append(pg.Vector2(x, y)) + self.road_pos_r.append(pg.Vector2(x, y)) if tile == "R": - self.roads_pos.append(pg.Vector2(x, y)) + self.road_pos_r.append(pg.Vector2(x, y)) + if tile == "G": + self.road_pos_g.append(pg.Vector2(x,y)) if tile == "H": self.houses_pos.append(pg.Vector2(x, y)) self.entities.append(HouseEntity(self, pg.Vector2(x, y))) @@ -132,7 +152,12 @@ class SimulationState: def update(self, move_agent): for entity in self.entities: if entity.entity_type == 'truck': - entity.move(move_agent) + if isinstance(move_agent, int): + entity.orientation = move_agent + entity.rotate_img(move_agent) + + else: + entity.move(move_agent) class Layer: @@ -140,7 +165,7 @@ class Layer: self.sim = sim self.texture_atlas = pg.image.load(texture_file) - def renderTile(self, surface, position, tile): + def renderTile(self, surface, position, tile, orientation = 90, rotate=False): # pozycja na ekranie sprite_pos = position.elementwise() * self.sim.cell_size @@ -150,6 +175,7 @@ class Layer: int(pos_in_atlas.y), self.sim.cell_size.x, self.sim.cell_size.y) + # render surface.blit(self.texture_atlas, sprite_pos, texture) @@ -166,7 +192,10 @@ class EntityLayer(Layer): def render(self, surface): for entity in self.entities: - self.renderTile(surface, entity.position, entity.tile) + if entity.entity_type == 'truck': + self.renderTile(surface, entity.position, entity.tile, entity.orientation, rotate=True) + else: + self.renderTile(surface, entity.position, entity.tile) class StructureLayer(Layer): @@ -194,8 +223,9 @@ class Interface: # rendering self.cell_size = pg.Vector2(64, 64) - texture_file = Path("../res/tiles.png") - self.layers = [StructureLayer(self, texture_file, self.state, self.state.roads_pos, ROAD_SPRITE), + texture_file = Path(r"..\res\tiles.png") + self.layers = [StructureLayer(self, texture_file, self.state, self.state.road_pos_r, ROAD_SPRITE_R ), + StructureLayer(self, texture_file, self.state, self.state.road_pos_g, ROAD_SPRITE_G ), EntityLayer(self, texture_file, self.state, self.state.entities)] # okno @@ -227,12 +257,16 @@ class Interface: if self.debug_mode: if event.key == pg.K_RIGHT: self.move_truck.x = 1 + if event.key == pg.K_LEFT: self.move_truck.x = -1 + if event.key == pg.K_DOWN: self.move_truck.y = 1 + if event.key == pg.K_UP: self.move_truck.y = -1 + if event.key == pg.K_d: self.agent.discover() @@ -242,6 +276,9 @@ class Interface: def update(self): self.state.update(self.move_truck) self.agent.update() + if isinstance(self.move_truck, int): + self.state.update(self.move_truck) + self.agent.update() def render(self): if not self.debug_mode: @@ -262,4 +299,4 @@ class Interface: self.update() self.render() self.clock.tick(24) - pg.quit() + pg.quit() \ No newline at end of file