diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 986edd4..a180c67 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,9 +3,10 @@ - + + @@ -123,42 +125,42 @@ - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + @@ -172,6 +174,6 @@ - + \ No newline at end of file diff --git a/__pycache__/definitions.cpython-37.pyc b/__pycache__/definitions.cpython-37.pyc index 8c27e97..aae9f00 100644 Binary files a/__pycache__/definitions.cpython-37.pyc and b/__pycache__/definitions.cpython-37.pyc differ diff --git a/__pycache__/graph.cpython-37.pyc b/__pycache__/graph.cpython-37.pyc index 97f9fab..66a7a5e 100644 Binary files a/__pycache__/graph.cpython-37.pyc and b/__pycache__/graph.cpython-37.pyc differ diff --git a/__pycache__/plant.cpython-37.pyc b/__pycache__/plant.cpython-37.pyc index cf65735..238da7a 100644 Binary files a/__pycache__/plant.cpython-37.pyc and b/__pycache__/plant.cpython-37.pyc differ diff --git a/__pycache__/tractor.cpython-37.pyc b/__pycache__/tractor.cpython-37.pyc index b84c0a7..8b78c04 100644 Binary files a/__pycache__/tractor.cpython-37.pyc and b/__pycache__/tractor.cpython-37.pyc differ diff --git a/graph.py b/graph.py index 927c5a4..1f81e00 100644 --- a/graph.py +++ b/graph.py @@ -1,10 +1,27 @@ import copy import tractor -class Node: - def __init__(self, action, direction, parent, x, y): - self.action = action +class Istate: #stan początkowy traktora (strona, w którą patrzy, miejsce, w którym się on znajduje) + def __init__(self, direction, x, y): self.direction = direction - self.parent = parent + self.x = x + self.y = y + def get_direction(self): + return self.direction + def set_direction(self, direction): + self.direction = direction + def get_x(self): + return self.x + def set_x(self, x): + self.x = x + def get_y(self): + return self.y + def set_y(self, y): + self.y = y +class Node: #wierzchołek grafu + def __init__(self, action, direction, parent, x, y): + self.action = action #akcja jaką ma wykonać (obróc się w lewo, obróć się w prawo, ruch do przodu) + self.direction = direction + self.parent = parent #ojciec wierzchołka self.x = x self.y = y def get_action(self): @@ -27,47 +44,19 @@ class Node: return self.y def set_y(self, y): self.y = y -class Istate: #stan początkowy traktora - def __init__(self, direction, x, y): - self.direction = direction - self.x = x - self.y = y - def get_direction(self): - return self.direction - def set_direction(self, direction): - self.direction = direction - def get_x(self): - return self.x - def set_x(self, x): - self.x = x - def get_y(self): - return self.y - def set_y(self, y): - self.y = y -# class Fringe: #kolejka zawierająca akcje oraz pola do odwiedzenia -# def __init__(self, fringe): -# self.fringe = fringe -# def get_fringe(self): -# return self.fringe -# def set_fringe(self, fringe): -# self.fringe = fringe -# def add_to_fringe(self, value): -# self.fringe.append(value) -# def get_element_from_fringe_pop(self): -# return self.fringe.pop(0) -def goal_test(elem, goaltest): - if elem.get_x() == goaltest.get_x() and elem.get_y() == goaltest.get_y(): #goaltest bez getterów +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 else: return False -def print_moves(elem, explored): +def print_moves(elem): #zwraca listę ruchów jakie należy wykonać by dotrzeć do punktu docelowego moves_list = [] while (elem.get_parent() != None): moves_list.append(elem.get_action()) elem = elem.get_parent() moves_list.reverse() return moves_list -def succ(elem): +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 actions_list = [] temp = copy.copy(elem.get_direction()) if temp == 1: @@ -94,46 +83,24 @@ def succ(elem): elif tractor.Tractor.is_move_allowed_succ(elem) == "x - 1": actions_list.append(("move", (elem.get_direction(), temp_move_west, elem.get_y()))) return actions_list -def graphsearch(fringe, explored, istate, succ, goaltest): - node = Node(None, istate.get_direction(), None, istate.get_x(), istate.get_y()) #może None coś nie gra - #fringe.add_to_fringe(node) - fringe.append(node) +def graphsearch(fringe, explored, istate, succ, goaltest): #przeszukiwanie grafu wszerz + node = Node(None, istate.get_direction(), None, istate.get_x(), istate.get_y()) #wierzchołek początkowy, stworzony ze stanu początkowego traktora + fringe.append(node) #wierzchołki do odwiedzenia while True: if not fringe: return False - #elem = fringe.get_element_from_fringe_pop() - elem = fringe.pop(0) - temp = copy.copy(elem) #żeby explored w for succ() nie zmieniało - if goal_test(elem, goaltest) is True: - # for x in fringe: - # print("action: " + str(x.get_action())) - # print("direction: " + str(x.get_direction())) - # print("parent: " + str(x.get_parent())) - # print("node: " + str(x)) - # print("x: " + str(x.get_x())) - # print("y: " + str(x.get_y())) - # for x in explored: - # print("action ex: " + str(x.get_action())) - # print("direction ex: " + str(x.get_direction())) - # print("parent ex: " + str(x.get_parent())) - # print("node ex: " + str(x)) - # print("x ex: " + str(x.get_x())) - # print("y ex: " + str(x.get_y())) - return print_moves(elem, explored) - explored.append(elem) - for (action, state) in succ(temp): + elem = fringe.pop(0) #zdejmujemy wierzchołek z kolejki fringe i rozpatrujemy go + temp = copy.copy(elem) + if goal_test(elem, 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) + 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 = [] explored_tuple = [] for x in fringe: fringe_tuple.append((x.get_direction(), x.get_x(), x.get_y())) for x in explored: explored_tuple.append((x.get_direction(), x.get_x(), x.get_y())) - if state not in fringe_tuple and state not in explored_tuple: - x = Node(action, state[0], elem, state[1], state[2]) - # print(x.get_action()) - # print(state[0]) - # print(state[1]) - # print(state[2]) - # print(x.get_direction()) - # print(x.get_parent()) - fringe.append(x) \ No newline at end of file + 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 + x = Node(action, state[0], elem, state[1], state[2]) #stworzenie nowego wierzchołka, którego rodzicem jest elem + fringe.append(x) #dodanie wierzchołka na fringe \ No newline at end of file diff --git a/plant.py b/plant.py index fcc747a..afa337b 100644 --- a/plant.py +++ b/plant.py @@ -11,6 +11,34 @@ class Plant: return self.state def set_state(self, state): self.state = state + # @staticmethod + # def get_closest_mature_plant(map1, tractor1): + # x = -1 + # y = -1 + # min = definitions.WIDTH_AMOUNT + definitions.HEIGHT_AMOUNT + 1 + # for i in range(definitions.WIDTH_AMOUNT): + # for j in range(definitions.HEIGHT_AMOUNT): + # field = map1.get_fields()[i][j] + # if field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE: #and abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) < min: + # x = i + # y = j + # min = abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) + # elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE: #and abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) < min: + # x = i + # y = j + # min = abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) + # elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE: #and abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) < min: + # x = i + # y = j + # min = abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) + # elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE: #and abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) < min: + # x = i + # y = j + # min = abs(tractor1.get_x() - i) + abs(tractor1.get_y() - j) + # if x == -1 and y == -1: + # return False + # else: + # return x, y @staticmethod def grow_plants(map1): #metoda statyczna, która zwiększa pole state (etap rozwoju rośliny) dla danej rośliny na danym polu o 1 for i in range(definitions.WIDTH_AMOUNT): diff --git a/py.py b/py.py index eadede4..d58c500 100644 --- a/py.py +++ b/py.py @@ -3,6 +3,7 @@ import graph import map import plant import pygame +import random import station import tractor pygame.display.set_caption("Smart Tractor") @@ -10,11 +11,12 @@ def main(): #tworzenie podstawowych obiektów map1 = map.Map([]) map1.create_base_map() + move_list = [] amount_of_seeds_dict = {"beetroot": definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE, "carrot": definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE, "potato": definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE, "wheat": definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE} collected_plants_dict = {"beetroot": 0, "carrot": 0, "potato": 0, "wheat": 0} fertilizer_dict = {"beetroot": definitions.TRACTOR_FERTILIZER, "carrot": definitions.TRACTOR_FERTILIZER, "potato": definitions.TRACTOR_FERTILIZER, "wheat": definitions.TRACTOR_FERTILIZER} station1 = station.Station(collected_plants_dict) - tractor1 = tractor.Tractor(amount_of_seeds_dict, collected_plants_dict, definitions.TRACTOR_DIRECTION_SOUTH, fertilizer_dict, definitions.TRACTOR_FUEL, definitions.TRACTOR_WATER_LEVEL, 0, 0) + tractor1 = tractor.Tractor(amount_of_seeds_dict, collected_plants_dict, definitions.TRACTOR_DIRECTION_NORTH, fertilizer_dict, definitions.TRACTOR_FUEL, definitions.TRACTOR_WATER_LEVEL, 0, 0) tractor1_rect = pygame.Rect(tractor1.get_x(), tractor1.get_y(), definitions.BLOCK_SIZE, definitions.BLOCK_SIZE) clock = pygame.time.Clock() run = True @@ -23,11 +25,17 @@ def main(): for event in pygame.event.get(): if event.type == pygame.QUIT: run = False - istate = graph.Istate(definitions.TRACTOR_DIRECTION_SOUTH, 0, 0) - istate1 = graph.Istate(None, 4, 6) - print(graph.graphsearch([], [], istate, graph.succ, istate1)) map1.draw_window(tractor1, tractor1_rect) - tractor1.tractor1_handle_movement(tractor1_rect) + if not move_list: + istate = graph.Istate(tractor1.get_direction(), 0, 0) + move_list = (graph.graphsearch([], [], istate, graph.succ, (4, 4))) + print(move_list) + elif move_list: + temp = move_list.pop(0) + print(temp) + tractor1.handle_movement(temp, tractor1_rect) + else: + tractor1.handle_random_movement(tractor1_rect) tractor1.do_work(map1, station1, tractor1_rect) plant.Plant.grow_plants(map1) pygame.quit() diff --git a/tractor.py b/tractor.py index 23da023..08173c5 100644 --- a/tractor.py +++ b/tractor.py @@ -184,17 +184,30 @@ class Tractor: return "x - 1" else: return False - def tractor1_handle_movement(self, tractor1_rect): #odpowiada za poruszanie się traktora po mapie + def handle_movement(self, move, tractor1_rect): #odpowiada za poruszanie się traktora po mapie + if self.get_fuel() > 0: + if move == "move": + self.move() + elif move == "rotate_left": + self.rotate_left() + elif move == "rotate_right": + self.rotate_right() + self.set_fuel(self.get_fuel() - 1) + tractor1_rect.x = self.get_x() + tractor1_rect.y = self.get_y() + def handle_random_movement(self, tractor1_rect): #odpowiada za losowe poruszanie się traktora po mapie loop = True while loop and self.get_fuel() > 0: - if self.is_move_allowed(tractor1_rect) is True: + random1 = random.randint(1, 3) + if random1 == 1 and self.is_move_allowed(tractor1_rect) is True: self.move() tractor1_rect.x = self.get_x() tractor1_rect.y = self.get_y() loop = False - else: + elif random1 == 2: + self.rotate_left() + loop = False + elif random1 == 3: self.rotate_right() - self.set_fuel(self.get_fuel() - 1) - if tractor1_rect.x == 0 and tractor1_rect.y == 0: - self.set_fuel(definitions.TRACTOR_FUEL) - self.set_water_level(definitions.TRACTOR_WATER_LEVEL) \ No newline at end of file + loop = False + self.set_fuel(self.get_fuel() - 1) \ No newline at end of file