diff --git a/.idea/workspace.xml b/.idea/workspace.xml index cdbaa44..b4ac252 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,6 +3,8 @@ + + @@ -119,6 +121,8 @@ + + @@ -130,42 +134,42 @@ - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + @@ -179,6 +183,6 @@ - + \ No newline at end of file diff --git a/__pycache__/astar.cpython-37.pyc b/__pycache__/astar.cpython-37.pyc index 62d6e65..d47d559 100644 Binary files a/__pycache__/astar.cpython-37.pyc and b/__pycache__/astar.cpython-37.pyc differ diff --git a/__pycache__/definitions.cpython-37.pyc b/__pycache__/definitions.cpython-37.pyc index 9145f88..c2bfb11 100644 Binary files a/__pycache__/definitions.cpython-37.pyc and b/__pycache__/definitions.cpython-37.pyc differ diff --git a/__pycache__/map.cpython-37.pyc b/__pycache__/map.cpython-37.pyc index 591093b..c130e6a 100644 Binary files a/__pycache__/map.cpython-37.pyc and b/__pycache__/map.cpython-37.pyc differ diff --git a/astar.py b/astar.py index 827d015..a2c022e 100644 --- a/astar.py +++ b/astar.py @@ -46,13 +46,15 @@ class Node: #wierzchołek grafu def set_y(self, y): self.y = y def cost(map, node): #funkcja kosztu : ile kosztuje przejechanie przez dane pole - return map.get_field_cost(int(node.get_x()), int(node.get_y())) + cost = 0 + while(node.get_parent() != None): + cost = cost + map.get_field_cost(int(node.get_x()), int(node.get_y())) + 1 + node = node.get_parent() + return cost def heuristic(node, goaltest): #funkcja heurestyki : oszacowuje koszt osiągnięcia stanu końcowego (droga) return abs(node.get_x() - goaltest[0]) + abs(node.get_y() - goaltest[1]) def f(map, node, goaltest): #funkcja zwracająca sumę funkcji kosztu oraz heurestyki return cost(map, node) + heuristic(node, goaltest) -# def optimal_goal_test(): - def goal_test(elem, goaltest): #funkcja sprawdzająca czy położenie traktora równa się położeniu punktu docelowego, jeśli tak zwraca prawdę, w przeciwnym wypadku fałsz if elem.get_x() == goaltest[0] and elem.get_y() == goaltest[1]: return True @@ -60,9 +62,9 @@ def goal_test(elem, goaltest): #funkcja sprawdzająca czy położenie traktora r return False def print_moves(elem): #zwraca listę ruchów jakie należy wykonać by dotrzeć do punktu docelowego moves_list = [] - while (elem[0].get_parent() != None): - moves_list.append(elem[0].get_action()) - elem = elem[0].get_parent() + while (elem.get_parent() != None): + moves_list.append(elem.get_action()) + elem = elem.get_parent() moves_list.reverse() return moves_list def succ(elem): #funkcja następnika, przypisuje jakie akcje są możliwe do wykonania na danym polu oraz jaki będzie stan (kierunek, położenie) po wykonaniu tej akcji @@ -101,18 +103,18 @@ def graphsearch(fringe, explored, istate, succ, goaltest, f, map): #przeszukiwan elem = fringe.pop(0) #zdejmujemy wierzchołek z kolejki fringe i rozpatrujemy go temp = copy.copy(elem[0]) if goal_test(elem[0], goaltest) is True: #jeżeli osiągniemy cel w trakcie przeszukiwania grafu wszerz (wjedziemy na pole docelowe) : zwracamy listę ruchów, po których wykonaniu dotrzemy na miejsce - return print_moves(elem) + return print_moves(elem[0]) explored.append(elem) #dodajemy wierzchołek do listy wierzchołków odwiedzonych for (action, state) in succ(temp): #iterujemy po wszystkich możliwych akcjach i stanach otrzymanych dla danego wierzchołka grafu fringe_tuple = [] fringe_tuple_prio = [] explored_tuple = [] - for (x, y) in fringe: + for (x, y) in fringe: fringe_tuple.append((x.get_direction(), x.get_x(), x.get_y())) fringe_tuple_prio.append(((x.get_direction(), x.get_x(), x.get_y()), y)) for (x, y) in explored: explored_tuple.append((x.get_direction(), x.get_x(), x.get_y())) - x = Node(action, state[0], elem, state[1], state[2]) #stworzenie nowego wierzchołka, którego rodzicem jest elem + x = Node(action, state[0], elem[0], state[1], state[2]) #stworzenie nowego wierzchołka, którego rodzicem jest elem p = f(map, x, goaltest) #liczy priorytet if state not in fringe_tuple and state not in explored_tuple: #jeżeli stan nie znajduje się na fringe oraz nie znajduje się w liście wierzchołków odwiedzonych fringe.append((x, p)) #dodanie wierzchołka na fringe @@ -123,6 +125,7 @@ def graphsearch(fringe, explored, istate, succ, goaltest, f, map): #przeszukiwan if str(state_prio) == str(state): if r > p: fringe.insert(i, (x, p)) #zamiana state, który należy do fringe z priorytetem r na state z priorytetem p (niższym) + fringe.pop(i + 1) fringe = sorted(fringe, key=itemgetter(1)) #sortowanie fringe'a według priorytetu break i = i + 1 \ No newline at end of file diff --git a/definitions.py b/definitions.py index 2ee2ec4..41cbb97 100644 --- a/definitions.py +++ b/definitions.py @@ -2,6 +2,8 @@ import os import pygame BLOCK_SIZE = 60 +BEETROOTS_ADULT_COST = 4 +BEETROOTS_GROW_COST = 10 BEETROOTS_GROW_TIME = 5 BEETROOTS_MAXIMUM_STATE = BEETROOTS_GROW_TIME * 3 + 1 BEETROOTS_STAGE_0 = pygame.image.load(os.path.join('resources', 'beetroots_stage_0.png')) @@ -12,6 +14,8 @@ BEETROOTS_STAGE_2 = pygame.image.load(os.path.join('resources', 'beetroots_stage BEETROOTS_STAGE_2 = pygame.transform.scale(BEETROOTS_STAGE_2, (BLOCK_SIZE, BLOCK_SIZE)) BEETROOTS_STAGE_3 = pygame.image.load(os.path.join('resources', 'beetroots_stage_3.png')) BEETROOTS_STAGE_3 = pygame.transform.scale(BEETROOTS_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE)) +CARROTS_ADULT_COST = 4 +CARROTS_GROW_COST = 10 CARROTS_GROW_TIME = 5 CARROTS_MAXIMUM_STATE = CARROTS_GROW_TIME * 3 + 1 CARROTS_STAGE_0 = pygame.image.load(os.path.join('resources', 'carrots_stage_0.png')) @@ -24,13 +28,18 @@ CARROTS_STAGE_3 = pygame.image.load(os.path.join('resources', 'carrots_stage_3.p CARROTS_STAGE_3 = pygame.transform.scale(CARROTS_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE)) DIRT = pygame.image.load(os.path.join('resources', 'dirt.png')) DIRT = pygame.transform.scale(DIRT, (BLOCK_SIZE, BLOCK_SIZE)) +DIRT_COST = 2 HEIGHT_AMOUNT, WIDTH_AMOUNT = 10, 10 HEIGHT, WIDTH = BLOCK_SIZE * HEIGHT_AMOUNT, BLOCK_SIZE * WIDTH_AMOUNT FARMLAND_DRY = pygame.image.load(os.path.join('resources', 'farmland_dry.png')) FARMLAND_DRY = pygame.transform.scale(FARMLAND_DRY, (BLOCK_SIZE, BLOCK_SIZE)) +FARMLAND_DRY_COST = 3 FARMLAND_WET = pygame.image.load(os.path.join('resources', 'farmland_wet.png')) FARMLAND_WET = pygame.transform.scale(FARMLAND_WET, (BLOCK_SIZE, BLOCK_SIZE)) -FPS = 1 +FARMLAND_WET_COST = 1 +FPS = 10 +POTATOES_ADULT_COST = 4 +POTATOES_GROW_COST = 10 POTATOES_GROW_TIME = 5 POTATOES_MAXIMUM_STATE = POTATOES_GROW_TIME * 3 + 1 POTATOES_STAGE_0 = pygame.image.load(os.path.join('resources', 'potatoes_stage_0.png')) @@ -45,6 +54,7 @@ SPONGE = pygame.image.load(os.path.join('resources', 'sponge.png')) SPONGE = pygame.transform.scale(SPONGE, (BLOCK_SIZE, BLOCK_SIZE)) STATION = pygame.image.load(os.path.join('resources', 'rail_normal.png')) STATION = pygame.transform.scale(STATION, (BLOCK_SIZE, BLOCK_SIZE)) +STATION_COST = 5 TRACTOR_DIRECTION_EAST_TEXTURE = pygame.image.load(os.path.join('resources', 'minecart_command_block_east.png')) TRACTOR_DIRECTION_EAST_TEXTURE = pygame.transform.scale(TRACTOR_DIRECTION_EAST_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) TRACTOR_DIRECTION_NORTH_TEXTURE = pygame.image.load(os.path.join('resources', 'minecart_command_block_north.png')) @@ -58,10 +68,12 @@ TRACTOR_DIRECTION_NORTH = 1 TRACTOR_DIRECTION_SOUTH = 3 TRACTOR_DIRECTION_WEST = 4 TRACTOR_FERTILIZER = 2 -TRACTOR_FUEL = 200 +TRACTOR_FUEL = 99999999999999 TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE = 20 TRACTOR_MAXIMUM_COLLECTED_PLANTS = 80 TRACTOR_WATER_LEVEL = 40 +WHEAT_ADULT_COST = 4 +WHEAT_GROW_COST = 10 WHEAT_GROW_TIME = 5 WHEAT_MAXIMUM_STATE = WHEAT_GROW_TIME * 7 + 1 WHEAT_STAGE_0 = pygame.image.load(os.path.join('resources', 'wheat_stage_0.png')) diff --git a/map.py b/map.py index ccbf047..422643d 100644 --- a/map.py +++ b/map.py @@ -23,32 +23,6 @@ class Map: temp_field = field.Field(temp_plant, temp_rect, temp_soil) temp_map_field.append(temp_field) self.fields.append(temp_map_field) - def get_field_cost(self, x, y): #zwraca koszt danego pola - field = self.fields[x][y] - if field.get_plant().get_name() == "station" and field.get_plant().get_state() == -1: - return 5 - elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.BEETROOTS_GROW_TIME: - return 10 - elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE: - return 4 - elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.CARROTS_GROW_TIME: - return 10 - elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE: - return 4 - elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.POTATOES_GROW_TIME: - return 10 - elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE: - return 4 - elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 7 * definitions.WHEAT_GROW_TIME: - return 10 - elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE: - return 4 - elif field.get_soil().get_state() is False: - return 2 - elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is False: - return 3 - elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is True: - return 1 def fill_map(self): #wypełnia mapę teksturami na podstawie logicznego stanu pól for i in range(definitions.WIDTH_AMOUNT): for j in range(definitions.HEIGHT_AMOUNT): @@ -107,6 +81,32 @@ class Map: elif block != definitions.DIRT or block != definitions.FARMLAND_DRY or block != definitions.FARMLAND_WET: definitions.WINDOW.blit(definitions.FARMLAND_WET, (rect.x, rect.y)) definitions.WINDOW.blit(block, (rect.x, rect.y)) + def get_field_cost(self, x, y): #zwraca koszt danego pola + field = self.fields[x][y] + if field.get_plant().get_name() == "station" and field.get_plant().get_state() == -1: + return definitions.STATION_COST + elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.BEETROOTS_GROW_TIME: + return definitions.BEETROOTS_GROW_COST + elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE: + return definitions.BEETROOTS_ADULT_COST + elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.CARROTS_GROW_TIME: + return definitions.CARROTS_GROW_COST + elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE: + return definitions.CARROTS_ADULT_COST + elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.POTATOES_GROW_TIME: + return definitions.POTATOES_GROW_COST + elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE: + return definitions.POTATOES_ADULT_COST + elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 7 * definitions.WHEAT_GROW_TIME: + return definitions.WHEAT_GROW_COST + elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE: + return definitions.WHEAT_ADULT_COST + elif field.get_soil().get_state() is False: + return definitions.DIRT_COST + elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is False: + return definitions.FARMLAND_DRY_COST + elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is True: + return definitions.FARMLAND_WET_COST def draw_window(self, tractor1, tractor1_rect): #rysuje mapę self.fill_map() if tractor1.get_direction() == definitions.TRACTOR_DIRECTION_EAST: diff --git a/py.py b/py.py index 5cc80e7..7a17ea3 100644 --- a/py.py +++ b/py.py @@ -29,7 +29,7 @@ def main(): if not move_list and plant.Plant.if_any_mature_plant(map1) is True: #jeżeli są jakieś ruchy do wykonania w move_list oraz istnieje jakaś dojrzała roślina istate = graph.Istate(tractor1.get_direction(), tractor1.get_x() / definitions.BLOCK_SIZE, tractor1.get_y() / definitions.BLOCK_SIZE) #stan początkowy traktora (jego orientacja oraz jego aktualne współrzędne) #move_list = (graph.graphsearch([], [], istate, graph.succ, plant.Plant.get_closest_mature_plant(map1, tractor1))) #lista z ruchami, które należy po kolei wykonać, graph - move_list = (astar.graphsearch([], [], istate, graph.succ, plant.Plant.get_closest_mature_plant(map1, tractor1), astar.f, map1)) #lista z ruchami, które należy po kolei wykonać, astar + move_list = (astar.graphsearch([], [], istate, graph.succ, plant.Plant.get_closest_mature_plant(map1, istate), astar.f, map1)) #lista z ruchami, które należy po kolei wykonać, astar elif move_list: #jeżeli move_list nie jest pusta tractor1.handle_movement(move_list.pop(0), tractor1_rect) #wykonaj kolejny ruch oraz zdejmij ten ruch z początku listy else: