diff --git a/.idea/SmartTractor.iml b/.idea/SmartCart.iml similarity index 100% rename from .idea/SmartTractor.iml rename to .idea/SmartCart.iml diff --git a/.idea/modules.xml b/.idea/modules.xml index 477f5bd..6d43d3d 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index fd9d236..300aef3 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,8 +2,49 @@ + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - + + - + + - + + - + + @@ -184,10 +252,15 @@ - + - + + + + + + @@ -201,6 +274,7 @@ - + + \ No newline at end of file diff --git a/__pycache__/astar.cpython-37.pyc b/__pycache__/astar.cpython-37.pyc index 287907e..540fd48 100644 Binary files a/__pycache__/astar.cpython-37.pyc and b/__pycache__/astar.cpython-37.pyc differ diff --git a/__pycache__/cart.cpython-37.pyc b/__pycache__/cart.cpython-37.pyc new file mode 100644 index 0000000..70275bf Binary files /dev/null and b/__pycache__/cart.cpython-37.pyc differ diff --git a/__pycache__/definitions.cpython-37.pyc b/__pycache__/definitions.cpython-37.pyc index 12d2ce0..7c199b8 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 91db8da..d9bc7b6 100644 Binary files a/__pycache__/graph.cpython-37.pyc and b/__pycache__/graph.cpython-37.pyc differ diff --git a/__pycache__/map.cpython-37.pyc b/__pycache__/map.cpython-37.pyc index 9fa61d7..0edec97 100644 Binary files a/__pycache__/map.cpython-37.pyc and b/__pycache__/map.cpython-37.pyc differ diff --git a/__pycache__/neuralnetwork.cpython-37.pyc b/__pycache__/neuralnetwork.cpython-37.pyc new file mode 100644 index 0000000..2b3ea84 Binary files /dev/null and b/__pycache__/neuralnetwork.cpython-37.pyc differ diff --git a/__pycache__/plant.cpython-37.pyc b/__pycache__/plant.cpython-37.pyc index 363305f..e47b153 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 deleted file mode 100644 index d816ea1..0000000 Binary files a/__pycache__/tractor.cpython-37.pyc and /dev/null differ diff --git a/__pycache__/treelearn.cpython-37.pyc b/__pycache__/treelearn.cpython-37.pyc index e58c682..07f9535 100644 Binary files a/__pycache__/treelearn.cpython-37.pyc and b/__pycache__/treelearn.cpython-37.pyc differ diff --git a/astar.py b/astar.py index a2c022e..01190dc 100644 --- a/astar.py +++ b/astar.py @@ -1,7 +1,7 @@ from operator import itemgetter +import cart import copy -import tractor -class Istate: #stan początkowy traktora (strona, w którą patrzy, miejsce, w którym się on znajduje) +class Istate: #stan początkowy wózka (strona, w którą patrzy, miejsce, w którym się on znajduje) def __init__(self, direction, x, y): self.direction = direction self.x = x @@ -51,51 +51,15 @@ def cost(map, node): #funkcja kosztu : ile kosztuje przejechanie przez dane pole 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 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 +def goal_test(elem, goaltest): #funkcja sprawdzająca czy położenie wózka 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): #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): #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: - temp = 4 - else: - temp = temp - 1 - actions_list.append(("rotate_left", (temp, elem.get_x(), elem.get_y()))) - temp = copy.copy(elem.get_direction()) - if temp == 4: - temp = 1 - else: - temp = temp + 1 - actions_list.append(("rotate_right", (temp, elem.get_x(), elem.get_y()))) - temp_move_south = elem.get_y() + 1 - temp_move_west = elem.get_x() - 1 - temp_move_east = elem.get_x() + 1 - temp_move_north = elem.get_y() - 1 - if tractor.Tractor.is_move_allowed_succ(elem) == "x + 1": - actions_list.append(("move", (elem.get_direction(), temp_move_east, elem.get_y()))) - elif tractor.Tractor.is_move_allowed_succ(elem) == "y - 1": - actions_list.append(("move", (elem.get_direction(), elem.get_x(), temp_move_north))) - elif tractor.Tractor.is_move_allowed_succ(elem) == "y + 1": - actions_list.append(("move", (elem.get_direction(), elem.get_x(), temp_move_south))) - 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, f, map): #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 + node = Node(None, istate.get_direction(), None, istate.get_x(), istate.get_y()) #wierzchołek początkowy, stworzony ze stanu początkowego wózka fringe.append((node, 0)) #wierzchołki do odwiedzenia z priorytetem while True: if not fringe: @@ -128,4 +92,40 @@ def graphsearch(fringe, explored, istate, succ, goaltest, f, map): #przeszukiwan 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 + i = i + 1 +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 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): #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: + temp = 4 + else: + temp = temp - 1 + actions_list.append(("rotate_left", (temp, elem.get_x(), elem.get_y()))) + temp = copy.copy(elem.get_direction()) + if temp == 4: + temp = 1 + else: + temp = temp + 1 + actions_list.append(("rotate_right", (temp, elem.get_x(), elem.get_y()))) + temp_move_south = elem.get_y() + 1 + temp_move_west = elem.get_x() - 1 + temp_move_east = elem.get_x() + 1 + temp_move_north = elem.get_y() - 1 + if cart.Cart.is_move_allowed_succ(elem) == "x + 1": + actions_list.append(("move", (elem.get_direction(), temp_move_east, elem.get_y()))) + elif cart.Cart.is_move_allowed_succ(elem) == "y - 1": + actions_list.append(("move", (elem.get_direction(), elem.get_x(), temp_move_north))) + elif cart.Cart.is_move_allowed_succ(elem) == "y + 1": + actions_list.append(("move", (elem.get_direction(), elem.get_x(), temp_move_south))) + elif cart.Cart.is_move_allowed_succ(elem) == "x - 1": + actions_list.append(("move", (elem.get_direction(), temp_move_west, elem.get_y()))) + return actions_list \ No newline at end of file diff --git a/tractor.py b/cart.py similarity index 76% rename from tractor.py rename to cart.py index 163485e..22accce 100644 --- a/tractor.py +++ b/cart.py @@ -1,6 +1,6 @@ import definitions import random -class Tractor: +class Cart: def __init__(self, amount_of_seeds, collected_plants, direction, fertilizer, fuel, water_level, x, y): self.amount_of_seeds = amount_of_seeds #amount_of_seeds to słownik, przechowuje informacje o posiadanej ilości ziaren dla danej rośliny self.collected_plants = collected_plants #collected_plants to słownik, przechowuje informacje o zebranych plonach @@ -48,50 +48,12 @@ class Tractor: return self.y def set_y(self, y): self.y = y - def move(self): - if self.direction == definitions.TRACTOR_DIRECTION_EAST: - self.x = self.x + definitions.BLOCK_SIZE - elif self.direction == definitions.TRACTOR_DIRECTION_NORTH: - self.y = self.y - definitions.BLOCK_SIZE - elif self.direction == definitions.TRACTOR_DIRECTION_SOUTH: - self.y = self.y + definitions.BLOCK_SIZE - elif self.direction == definitions.TRACTOR_DIRECTION_WEST: - self.x = self.x - definitions.BLOCK_SIZE - def rotate_left(self): - if self.direction == 1: - self.direction = 4 - else: - self.direction = self.direction - 1 - def rotate_right(self): - if self.direction == 4: - self.direction = 1 - else: - self.direction = self.direction + 1 - def station_restore(self, station1): #aktualizuje stan stacji pod względem oddanych plonów oraz uzupełnia zapasy traktora - station1.set_collected_plants("beetroot", station1.get_collected_plants("beetroot") + self.get_collected_plants("beetroot")) - self.set_collected_plants("beetroot", 0) - station1.set_collected_plants("carrot", station1.get_collected_plants("carrot") + self.get_collected_plants("carrot")) - self.set_collected_plants("carrot", 0) - station1.set_collected_plants("potato", station1.get_collected_plants("potato") + self.get_collected_plants("potato")) - self.set_collected_plants("potato", 0) - station1.set_collected_plants("wheat", station1.get_collected_plants("wheat") + self.get_collected_plants("wheat")) - self.set_collected_plants("wheat", 0) - self.set_amount_of_seeds("beetroot", definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE) - self.set_amount_of_seeds("carrot", definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE) - self.set_amount_of_seeds("potato", definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE) - self.set_amount_of_seeds("wheat", definitions.TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE) - self.set_fertilizer("beetroot", definitions.TRACTOR_FERTILIZER) - self.set_fertilizer("carrot", definitions.TRACTOR_FERTILIZER) - self.set_fertilizer("potato", definitions.TRACTOR_FERTILIZER) - self.set_fertilizer("wheat", definitions.TRACTOR_FERTILIZER) - self.set_fuel(definitions.TRACTOR_FUEL) - self.set_water_level(definitions.TRACTOR_WATER_LEVEL) - def do_work(self, map1, station1, tractor1_rect): #jaką pracę traktor ma wykonać na danym polu, na którym aktualnie przebywa (zmienia stan logiczny danego pola) + def do_work(self, map1, station1, cart_rect): #jaką pracę wózek ma wykonać na danym polu, na którym aktualnie przebywa (zmienia stan logiczny danego pola) loop = True if self.get_all_amount_of_seeds() == 0: loop = False - x = int(tractor1_rect.x / definitions.BLOCK_SIZE) - y = int(tractor1_rect.y / definitions.BLOCK_SIZE) + x = int(cart_rect.x / definitions.BLOCK_SIZE) + y = int(cart_rect.y / definitions.BLOCK_SIZE) field = map1.get_fields()[x][y] if x == 0 and y == 0: self.station_restore(station1) @@ -139,54 +101,31 @@ class Tractor: self.set_fertilizer("wheat", (self.get_fertilizer("wheat") - 1)) field.get_soil().set_is_fertilized(True) field.get_plant().set_state(field.get_plant().get_state() + definitions.WHEAT_GROW_TIME) - elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.TRACTOR_MAXIMUM_COLLECTED_PLANTS: + elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.CART_MAXIMUM_COLLECTED_PLANTS: field.get_plant().set_state(0) field.get_soil().set_is_fertilized(False) field.get_soil().set_water_level(False) field.get_soil().set_state(False) self.set_collected_plants("beetroot", self.get_collected_plants("beetroot") + 1) - elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.TRACTOR_MAXIMUM_COLLECTED_PLANTS: + elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.CART_MAXIMUM_COLLECTED_PLANTS: field.get_plant().set_state(0) field.get_soil().set_is_fertilized(False) field.get_soil().set_water_level(False) field.get_soil().set_state(False) self.set_collected_plants("carrot", self.get_collected_plants("carrot") + 1) - elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.TRACTOR_MAXIMUM_COLLECTED_PLANTS: + elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.CART_MAXIMUM_COLLECTED_PLANTS: field.get_plant().set_state(0) field.get_soil().set_is_fertilized(False) field.get_soil().set_water_level(False) field.get_soil().set_state(False) self.set_collected_plants("potato", self.get_collected_plants("potato") + 1) - elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.TRACTOR_MAXIMUM_COLLECTED_PLANTS: + elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE and self.get_all_collected_plants() < definitions.CART_MAXIMUM_COLLECTED_PLANTS: field.get_plant().set_state(0) field.get_soil().set_is_fertilized(False) field.get_soil().set_water_level(False) field.get_soil().set_state(False) self.set_collected_plants("wheat", self.get_collected_plants("wheat") + 1) - def is_move_allowed(self, tractor1_rect): #sprawdza czy dany ruch, który chce wykonać traktor jest możliwy, zwraca prawdę lub fałsz - if self.direction == definitions.TRACTOR_DIRECTION_EAST and tractor1_rect.x + definitions.BLOCK_SIZE < definitions.WIDTH: - return True - elif self.direction == definitions.TRACTOR_DIRECTION_NORTH and tractor1_rect.y - definitions.BLOCK_SIZE >= 0: - return True - elif self.direction == definitions.TRACTOR_DIRECTION_SOUTH and tractor1_rect.y + definitions.BLOCK_SIZE < definitions.HEIGHT: - return True - elif self.direction == definitions.TRACTOR_DIRECTION_WEST and tractor1_rect.x - definitions.BLOCK_SIZE >= 0: - return True - else: - return False - @staticmethod - def is_move_allowed_succ(node): #sprawdza czy dany ruch, który chce wykonać traktor jest możliwy, zwraca pozycje po wykonaniu ruchu, wersja node - if node.get_direction() == definitions.TRACTOR_DIRECTION_EAST and node.get_x() * definitions.BLOCK_SIZE + definitions.BLOCK_SIZE < definitions.WIDTH: - return "x + 1" - elif node.get_direction() == definitions.TRACTOR_DIRECTION_NORTH and node.get_y() * definitions.BLOCK_SIZE - definitions.BLOCK_SIZE >= 0: - return "y - 1" - elif node.get_direction() == definitions.TRACTOR_DIRECTION_SOUTH and node.get_y() * definitions.BLOCK_SIZE + definitions.BLOCK_SIZE < definitions.HEIGHT: - return "y + 1" - elif node.get_direction() == definitions.TRACTOR_DIRECTION_WEST and node.get_x() * definitions.BLOCK_SIZE - definitions.BLOCK_SIZE >= 0: - return "x - 1" - else: - return False - def handle_movement(self, move, tractor1_rect): #odpowiada za poruszanie się traktora po mapie + def handle_movement(self, move, cart_rect): #odpowiada za poruszanie się wózka po mapie if self.get_fuel() > 0: if move == "move": self.move() @@ -195,16 +134,16 @@ class Tractor: 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 + cart_rect.x = self.get_x() + cart_rect.y = self.get_y() + def handle_movement_random(self, cart_rect): #odpowiada za losowe poruszanie się wózka po mapie loop = True while loop and self.get_fuel() > 0: random1 = random.randint(1, 3) - if random1 == 1 and self.is_move_allowed(tractor1_rect) is True: + if random1 == 1 and self.is_move_allowed(cart_rect) is True: self.move() - tractor1_rect.x = self.get_x() - tractor1_rect.y = self.get_y() + cart_rect.x = self.get_x() + cart_rect.y = self.get_y() loop = False elif random1 == 2: self.rotate_left() @@ -212,4 +151,65 @@ class Tractor: elif random1 == 3: self.rotate_right() loop = False - self.set_fuel(self.get_fuel() - 1) \ No newline at end of file + self.set_fuel(self.get_fuel() - 1) + def is_move_allowed(self, cart_rect): #sprawdza czy dany ruch, który chce wykonać wózek jest możliwy, zwraca prawdę lub fałsz + if self.direction == definitions.CART_DIRECTION_EAST and cart_rect.x + definitions.BLOCK_SIZE < definitions.WIDTH: + return True + elif self.direction == definitions.CART_DIRECTION_NORTH and cart_rect.y - definitions.BLOCK_SIZE >= 0: + return True + elif self.direction == definitions.CART_DIRECTION_SOUTH and cart_rect.y + definitions.BLOCK_SIZE < definitions.HEIGHT: + return True + elif self.direction == definitions.CART_DIRECTION_WEST and cart_rect.x - definitions.BLOCK_SIZE >= 0: + return True + else: + return False + @staticmethod + def is_move_allowed_succ(node): #sprawdza czy dany ruch, który chce wykonać wózek jest możliwy, zwraca pozycje po wykonaniu ruchu, wersja node + if node.get_direction() == definitions.CART_DIRECTION_EAST and node.get_x() * definitions.BLOCK_SIZE + definitions.BLOCK_SIZE < definitions.WIDTH: + return "x + 1" + elif node.get_direction() == definitions.CART_DIRECTION_NORTH and node.get_y() * definitions.BLOCK_SIZE - definitions.BLOCK_SIZE >= 0: + return "y - 1" + elif node.get_direction() == definitions.CART_DIRECTION_SOUTH and node.get_y() * definitions.BLOCK_SIZE + definitions.BLOCK_SIZE < definitions.HEIGHT: + return "y + 1" + elif node.get_direction() == definitions.CART_DIRECTION_WEST and node.get_x() * definitions.BLOCK_SIZE - definitions.BLOCK_SIZE >= 0: + return "x - 1" + else: + return False + def move(self): + if self.direction == definitions.CART_DIRECTION_EAST: + self.x = self.x + definitions.BLOCK_SIZE + elif self.direction == definitions.CART_DIRECTION_NORTH: + self.y = self.y - definitions.BLOCK_SIZE + elif self.direction == definitions.CART_DIRECTION_SOUTH: + self.y = self.y + definitions.BLOCK_SIZE + elif self.direction == definitions.CART_DIRECTION_WEST: + self.x = self.x - definitions.BLOCK_SIZE + def rotate_left(self): + if self.direction == 1: + self.direction = 4 + else: + self.direction = self.direction - 1 + def rotate_right(self): + if self.direction == 4: + self.direction = 1 + else: + self.direction = self.direction + 1 + def station_restore(self, station1): #aktualizuje stan stacji pod względem oddanych plonów oraz uzupełnia zapasy wózka + station1.set_collected_plants("beetroot", station1.get_collected_plants("beetroot") + self.get_collected_plants("beetroot")) + self.set_collected_plants("beetroot", 0) + station1.set_collected_plants("carrot", station1.get_collected_plants("carrot") + self.get_collected_plants("carrot")) + self.set_collected_plants("carrot", 0) + station1.set_collected_plants("potato", station1.get_collected_plants("potato") + self.get_collected_plants("potato")) + self.set_collected_plants("potato", 0) + station1.set_collected_plants("wheat", station1.get_collected_plants("wheat") + self.get_collected_plants("wheat")) + self.set_collected_plants("wheat", 0) + self.set_amount_of_seeds("beetroot", definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE) + self.set_amount_of_seeds("carrot", definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE) + self.set_amount_of_seeds("potato", definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE) + self.set_amount_of_seeds("wheat", definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE) + self.set_fertilizer("beetroot", definitions.CART_FERTILIZER) + self.set_fertilizer("carrot", definitions.CART_FERTILIZER) + self.set_fertilizer("potato", definitions.CART_FERTILIZER) + self.set_fertilizer("wheat", definitions.CART_FERTILIZER) + self.set_fuel(definitions.CART_FUEL) + self.set_water_level(definitions.CART_WATER_LEVEL) \ No newline at end of file diff --git a/definitions.py b/definitions.py index 5225869..bafcd24 100644 --- a/definitions.py +++ b/definitions.py @@ -6,35 +6,52 @@ 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')) +BEETROOTS_STAGE_0 = pygame.image.load(os.path.join('resources/images', 'beetroots_stage_0.png')) BEETROOTS_STAGE_0 = pygame.transform.scale(BEETROOTS_STAGE_0, (BLOCK_SIZE, BLOCK_SIZE)) -BEETROOTS_STAGE_1 = pygame.image.load(os.path.join('resources', 'beetroots_stage_1.png')) +BEETROOTS_STAGE_1 = pygame.image.load(os.path.join('resources/images', 'beetroots_stage_1.png')) BEETROOTS_STAGE_1 = pygame.transform.scale(BEETROOTS_STAGE_1, (BLOCK_SIZE, BLOCK_SIZE)) -BEETROOTS_STAGE_2 = pygame.image.load(os.path.join('resources', 'beetroots_stage_2.png')) +BEETROOTS_STAGE_2 = pygame.image.load(os.path.join('resources/images', 'beetroots_stage_2.png')) 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.image.load(os.path.join('resources/images', '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')) +CARROTS_STAGE_0 = pygame.image.load(os.path.join('resources/images', 'carrots_stage_0.png')) CARROTS_STAGE_0 = pygame.transform.scale(CARROTS_STAGE_0, (BLOCK_SIZE, BLOCK_SIZE)) -CARROTS_STAGE_1 = pygame.image.load(os.path.join('resources', 'carrots_stage_1.png')) +CARROTS_STAGE_1 = pygame.image.load(os.path.join('resources/images', 'carrots_stage_1.png')) CARROTS_STAGE_1 = pygame.transform.scale(CARROTS_STAGE_1, (BLOCK_SIZE, BLOCK_SIZE)) -CARROTS_STAGE_2 = pygame.image.load(os.path.join('resources', 'carrots_stage_2.png')) +CARROTS_STAGE_2 = pygame.image.load(os.path.join('resources/images', 'carrots_stage_2.png')) CARROTS_STAGE_2 = pygame.transform.scale(CARROTS_STAGE_2, (BLOCK_SIZE, BLOCK_SIZE)) -CARROTS_STAGE_3 = pygame.image.load(os.path.join('resources', 'carrots_stage_3.png')) +CARROTS_STAGE_3 = pygame.image.load(os.path.join('resources/images', 'carrots_stage_3.png')) CARROTS_STAGE_3 = pygame.transform.scale(CARROTS_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE)) -DIRT = pygame.image.load(os.path.join('resources', 'dirt.png')) +CART_DIRECTION_EAST_TEXTURE = pygame.image.load(os.path.join('resources/images', 'minecart_command_block_east.png')) +CART_DIRECTION_EAST_TEXTURE = pygame.transform.scale(CART_DIRECTION_EAST_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) +CART_DIRECTION_NORTH_TEXTURE = pygame.image.load(os.path.join('resources/images', 'minecart_command_block_north.png')) +CART_DIRECTION_NORTH_TEXTURE = pygame.transform.scale(CART_DIRECTION_NORTH_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) +CART_DIRECTION_SOUTH_TEXTURE = pygame.image.load(os.path.join('resources/images', 'minecart_command_block_south.png')) +CART_DIRECTION_SOUTH_TEXTURE = pygame.transform.scale(CART_DIRECTION_SOUTH_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) +CART_DIRECTION_WEST_TEXTURE = pygame.image.load(os.path.join('resources/images', 'minecart_command_block_west.png')) +CART_DIRECTION_WEST_TEXTURE = pygame.transform.scale(CART_DIRECTION_WEST_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) +CART_DIRECTION_EAST = 2 +CART_DIRECTION_NORTH = 1 +CART_DIRECTION_SOUTH = 3 +CART_DIRECTION_WEST = 4 +CART_FERTILIZER = 2 +CART_FUEL = 200 +CART_AMOUNT_OF_SEEDS_EACH_TYPE = 20 +CART_MAXIMUM_COLLECTED_PLANTS = 80 +CART_WATER_LEVEL = 40 +DIRT = pygame.image.load(os.path.join('resources/images', '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.image.load(os.path.join('resources/images', '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.image.load(os.path.join('resources/images', 'farmland_wet.png')) FARMLAND_WET = pygame.transform.scale(FARMLAND_WET, (BLOCK_SIZE, BLOCK_SIZE)) FARMLAND_WET_COST = 1 FPS = 1 @@ -42,54 +59,37 @@ 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')) +POTATOES_STAGE_0 = pygame.image.load(os.path.join('resources/images', 'potatoes_stage_0.png')) POTATOES_STAGE_0 = pygame.transform.scale(POTATOES_STAGE_0, (BLOCK_SIZE, BLOCK_SIZE)) -POTATOES_STAGE_1 = pygame.image.load(os.path.join('resources', 'potatoes_stage_1.png')) +POTATOES_STAGE_1 = pygame.image.load(os.path.join('resources/images', 'potatoes_stage_1.png')) POTATOES_STAGE_1 = pygame.transform.scale(POTATOES_STAGE_1, (BLOCK_SIZE, BLOCK_SIZE)) -POTATOES_STAGE_2 = pygame.image.load(os.path.join('resources', 'potatoes_stage_2.png')) +POTATOES_STAGE_2 = pygame.image.load(os.path.join('resources/images', 'potatoes_stage_2.png')) POTATOES_STAGE_2 = pygame.transform.scale(POTATOES_STAGE_2, (BLOCK_SIZE, BLOCK_SIZE)) -POTATOES_STAGE_3 = pygame.image.load(os.path.join('resources', 'potatoes_stage_3.png')) +POTATOES_STAGE_3 = pygame.image.load(os.path.join('resources/images', 'potatoes_stage_3.png')) POTATOES_STAGE_3 = pygame.transform.scale(POTATOES_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE)) -SPONGE = pygame.image.load(os.path.join('resources', 'sponge.png')) +SPONGE = pygame.image.load(os.path.join('resources/images', 'sponge.png')) SPONGE = pygame.transform.scale(SPONGE, (BLOCK_SIZE, BLOCK_SIZE)) -STATION = pygame.image.load(os.path.join('resources', 'rail_normal.png')) +STATION = pygame.image.load(os.path.join('resources/images', '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')) -TRACTOR_DIRECTION_NORTH_TEXTURE = pygame.transform.scale(TRACTOR_DIRECTION_NORTH_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) -TRACTOR_DIRECTION_SOUTH_TEXTURE = pygame.image.load(os.path.join('resources', 'minecart_command_block_south.png')) -TRACTOR_DIRECTION_SOUTH_TEXTURE = pygame.transform.scale(TRACTOR_DIRECTION_SOUTH_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) -TRACTOR_DIRECTION_WEST_TEXTURE = pygame.image.load(os.path.join('resources', 'minecart_command_block_west.png')) -TRACTOR_DIRECTION_WEST_TEXTURE = pygame.transform.scale(TRACTOR_DIRECTION_WEST_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE)) -TRACTOR_DIRECTION_EAST = 2 -TRACTOR_DIRECTION_NORTH = 1 -TRACTOR_DIRECTION_SOUTH = 3 -TRACTOR_DIRECTION_WEST = 4 -TRACTOR_FERTILIZER = 2 -TRACTOR_FUEL = 200 -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')) +WHEAT_STAGE_0 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_0.png')) WHEAT_STAGE_0 = pygame.transform.scale(WHEAT_STAGE_0, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_1 = pygame.image.load(os.path.join('resources', 'wheat_stage_1.png')) +WHEAT_STAGE_1 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_1.png')) WHEAT_STAGE_1 = pygame.transform.scale(WHEAT_STAGE_1, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_2 = pygame.image.load(os.path.join('resources', 'wheat_stage_2.png')) +WHEAT_STAGE_2 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_2.png')) WHEAT_STAGE_2 = pygame.transform.scale(WHEAT_STAGE_2, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_3 = pygame.image.load(os.path.join('resources', 'wheat_stage_3.png')) +WHEAT_STAGE_3 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_3.png')) WHEAT_STAGE_3 = pygame.transform.scale(WHEAT_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_4 = pygame.image.load(os.path.join('resources', 'wheat_stage_4.png')) +WHEAT_STAGE_4 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_4.png')) WHEAT_STAGE_4 = pygame.transform.scale(WHEAT_STAGE_4, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_5 = pygame.image.load(os.path.join('resources', 'wheat_stage_5.png')) +WHEAT_STAGE_5 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_5.png')) WHEAT_STAGE_5 = pygame.transform.scale(WHEAT_STAGE_5, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_6 = pygame.image.load(os.path.join('resources', 'wheat_stage_6.png')) +WHEAT_STAGE_6 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_6.png')) WHEAT_STAGE_6 = pygame.transform.scale(WHEAT_STAGE_6, (BLOCK_SIZE, BLOCK_SIZE)) -WHEAT_STAGE_7 = pygame.image.load(os.path.join('resources', 'wheat_stage_7.png')) +WHEAT_STAGE_7 = pygame.image.load(os.path.join('resources/images', 'wheat_stage_7.png')) WHEAT_STAGE_7 = pygame.transform.scale(WHEAT_STAGE_7, (BLOCK_SIZE, BLOCK_SIZE)) WINDOW = pygame.display.set_mode((WIDTH, HEIGHT)) \ No newline at end of file diff --git a/graph.py b/graph.py index 1f81e00..27c23c5 100644 --- a/graph.py +++ b/graph.py @@ -1,6 +1,6 @@ +import cart import copy -import tractor -class Istate: #stan początkowy traktora (strona, w którą patrzy, miejsce, w którym się on znajduje) +class Istate: #stan początkowy wózka (strona, w którą patrzy, miejsce, w którym się on znajduje) def __init__(self, direction, x, y): self.direction = direction self.x = x @@ -44,11 +44,32 @@ class Node: #wierzchołek grafu return self.y def set_y(self, y): self.y = y -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 +def goal_test(elem, goaltest): #funkcja sprawdzająca czy położenie wózka 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 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 wózka + fringe.append(node) #wierzchołki do odwiedzenia + while True: + if not fringe: + return False + 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: #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 def print_moves(elem): #zwraca listę ruchów jakie należy wykonać by dotrzeć do punktu docelowego moves_list = [] while (elem.get_parent() != None): @@ -74,33 +95,12 @@ def succ(elem): #funkcja następnika, przypisuje jakie akcje są możliwe do wyk temp_move_west = elem.get_x() - 1 temp_move_east = elem.get_x() + 1 temp_move_north = elem.get_y() - 1 - if tractor.Tractor.is_move_allowed_succ(elem) == "x + 1": + if cart.Cart.is_move_allowed_succ(elem) == "x + 1": actions_list.append(("move", (elem.get_direction(), temp_move_east, elem.get_y()))) - elif tractor.Tractor.is_move_allowed_succ(elem) == "y - 1": + elif cart.Cart.is_move_allowed_succ(elem) == "y - 1": actions_list.append(("move", (elem.get_direction(), elem.get_x(), temp_move_north))) - elif tractor.Tractor.is_move_allowed_succ(elem) == "y + 1": + elif cart.Cart.is_move_allowed_succ(elem) == "y + 1": actions_list.append(("move", (elem.get_direction(), elem.get_x(), temp_move_south))) - elif tractor.Tractor.is_move_allowed_succ(elem) == "x - 1": + elif cart.Cart.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): #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.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: #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 + return actions_list \ No newline at end of file diff --git a/map.py b/map.py index 422643d..0936c39 100644 --- a/map.py +++ b/map.py @@ -23,6 +23,17 @@ 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 draw_window(self, cart, cart_rect): #rysuje mapę + self.fill_map() + if cart.get_direction() == definitions.CART_DIRECTION_EAST: + definitions.WINDOW.blit(definitions.CART_DIRECTION_EAST_TEXTURE, (cart_rect.x, cart_rect.y)) + elif cart.get_direction() == definitions.CART_DIRECTION_NORTH: + definitions.WINDOW.blit(definitions.CART_DIRECTION_NORTH_TEXTURE, (cart_rect.x, cart_rect.y)) + elif cart.get_direction() == definitions.CART_DIRECTION_SOUTH: + definitions.WINDOW.blit(definitions.CART_DIRECTION_SOUTH_TEXTURE, (cart_rect.x, cart_rect.y)) + elif cart.get_direction() == definitions.CART_DIRECTION_WEST: + definitions.WINDOW.blit(definitions.CART_DIRECTION_WEST_TEXTURE, (cart_rect.x, cart_rect.y)) + pygame.display.update() 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): @@ -106,15 +117,4 @@ class Map: 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: - definitions.WINDOW.blit(definitions.TRACTOR_DIRECTION_EAST_TEXTURE, (tractor1_rect.x, tractor1_rect.y)) - elif tractor1.get_direction() == definitions.TRACTOR_DIRECTION_NORTH: - definitions.WINDOW.blit(definitions.TRACTOR_DIRECTION_NORTH_TEXTURE, (tractor1_rect.x, tractor1_rect.y)) - elif tractor1.get_direction() == definitions.TRACTOR_DIRECTION_SOUTH: - definitions.WINDOW.blit(definitions.TRACTOR_DIRECTION_SOUTH_TEXTURE, (tractor1_rect.x, tractor1_rect.y)) - elif tractor1.get_direction() == definitions.TRACTOR_DIRECTION_WEST: - definitions.WINDOW.blit(definitions.TRACTOR_DIRECTION_WEST_TEXTURE, (tractor1_rect.x, tractor1_rect.y)) - pygame.display.update() \ No newline at end of file + return definitions.FARMLAND_WET_COST \ No newline at end of file diff --git a/neuralnetwork.py b/neuralnetwork.py new file mode 100644 index 0000000..9660659 --- /dev/null +++ b/neuralnetwork.py @@ -0,0 +1,110 @@ +from PIL import Image +from torch.autograd import Variable +from torch.optim import Adam +from torch.utils.data import DataLoader +from torchvision.transforms import transforms +import glob +import numpy as np +import os +import pathlib +import torch +import torch.nn as nn +import torchvision +class ConvNet(nn.Module): + def __init__(self, num_classes=6): + super(ConvNet, self).__init__() + self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(num_features=12) + self.relu1 = nn.ReLU() + self.pool = nn.MaxPool2d(kernel_size=2) + self.conv2 = nn.Conv2d(in_channels=12, out_channels=20, kernel_size=3, stride=1, padding=1) + self.relu2 = nn.ReLU() + self.conv3 = nn.Conv2d(in_channels=20, out_channels=32, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(num_features=32) + self.relu3 = nn.ReLU() + self.fc = nn.Linear(in_features=75 * 75 * 32, out_features=num_classes) + def forward(self, input): + output = self.conv1(input) + output = self.bn1(output) + output = self.relu1(output) + output = self.pool(output) + output = self.conv2(output) + output = self.relu2(output) + output = self.conv3(output) + output = self.bn3(output) + output = self.relu3(output) + output = output.view(-1, 32 * 75 * 75) + output = self.fc(output) + return output +def create_neural_network(): + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + transformer = transforms.Compose([transforms.Resize((150, 150)), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])]) + train_path = os.path.join('resources/neural_network/train/') + test_path = os.path.join('resources/neural_network/test/') + pred_path = os.path.join('resources/neural_network/pred/') + train_loader = DataLoader(torchvision.datasets.ImageFolder(train_path, transform=transformer), batch_size=64, shuffle=True) + test_loader = DataLoader(torchvision.datasets.ImageFolder(test_path, transform=transformer), batch_size=32, shuffle=True) + root = pathlib.Path(train_path) + classes = sorted([j.name.split('/')[-1] for j in root.iterdir()]) + if os.path.exists("resources/neural_network/checkpoint.model"): + checkpoint = torch.load(os.path.join('resources/neural_network', 'checkpoint.model')) + model = ConvNet(num_classes=6) + model.load_state_dict(checkpoint) + model.eval() + transformer1 = transforms.Compose([transforms.Resize((150, 150)), transforms.ToTensor(), transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])]) + images_path = glob.glob(pred_path+'/*.jpg') + pred_dict = {} + for i in images_path: + pred_dict[i[i.rfind('/') + 1:]] = prediction1(i, transformer1, model, classes) + print(pred_dict) + else: + model = ConvNet(num_classes=6).to(device) + optimizer = Adam(model.parameters(), lr=0.001, weight_decay=0.0001) + loss_function = nn.CrossEntropyLoss() + num_epochs = 10 + train_count = len(glob.glob(train_path + '/**/*.jpg')) + test_count = len(glob.glob(test_path + '/**/*.jpg')) + best_accuracy = 0.0 + for epoch in range(num_epochs): + model.train() + train_accuracy = 0.0 + train_loss = 0.0 + for i, (images, labels) in enumerate(train_loader): + if torch.cuda.is_available(): + images = Variable(images.cuda()) + labels = Variable(labels.cuda()) + optimizer.zero_grad() + outputs = model(images) + loss = loss_function(outputs, labels) + loss.backward() + optimizer.step() + train_loss += loss.cpu().data * images.size(0) + _, prediction = torch.max(outputs.data, 1) + train_accuracy += int(torch.sum(prediction == labels.data)) + train_accuracy = train_accuracy / train_count + train_loss = train_loss / train_count + model.eval() + test_accuracy = 0.0 + for i, (images, labels) in enumerate(test_loader): + if torch.cuda.is_available(): + images = Variable(images.cuda()) + labels = Variable(labels.cuda()) + outputs = model(images) + _, prediction = torch.max(outputs.data, 1) + test_accuracy += int(torch.sum(prediction == labels.data)) + test_accuracy = test_accuracy / test_count + print('Epoch: ' + str(epoch) + ' Train Loss: ' + str(train_loss) + ' Train Accuracy: ' + str(train_accuracy) + ' Test Accuracy: ' + str(test_accuracy)) + if test_accuracy > best_accuracy: + torch.save(model.state_dict(), 'resources/neural_network/checkpoint.model') + best_accuracy = test_accuracy +def prediction1(img_path, transformer, model, classes): + image = Image.open(img_path) + image_tensor = transformer(image).float() + image_tensor = image_tensor.unsqueeze_(0) + if torch.cuda.is_available(): + image_tensor.cuda() + input = Variable(image_tensor) + output = model(input) + index = output.data.numpy().argmax() + pred = classes[index] + return pred \ No newline at end of file diff --git a/plant.py b/plant.py index dca31b2..6a5e1b4 100644 --- a/plant.py +++ b/plant.py @@ -12,6 +12,44 @@ class Plant: def set_state(self, state): self.state = state @staticmethod + def get_mature_plant(map1, cart): #pobiera współrzędne jakiejś dojrzałej rośliny + x = -1 + y = -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: + x = i + y = j + elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE: + x = i + y = j + elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE: + x = i + y = j + + elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE: + x = i + 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): + 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() > 0 and field.get_plant().get_state() < definitions.BEETROOTS_MAXIMUM_STATE: + field.get_plant().set_state(field.get_plant().get_state() + 1) + elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() < definitions.CARROTS_MAXIMUM_STATE: + field.get_plant().set_state(field.get_plant().get_state() + 1) + elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() > 0 and field.get_plant().get_state() < definitions.POTATOES_MAXIMUM_STATE: + field.get_plant().set_state(field.get_plant().get_state() + 1) + elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() > 0 and field.get_plant().get_state() < definitions.WHEAT_MAXIMUM_STATE: + field.get_plant().set_state(field.get_plant().get_state() + 1) + @staticmethod def if_any_mature_plant(map1): #sprawdza czy na polu występuje choć jedna dojrzała roślina, jeśli tak zwraca prawdę, w przeciwnym razie zwraca fałsz for i in range(definitions.WIDTH_AMOUNT): for j in range(definitions.HEIGHT_AMOUNT): @@ -24,45 +62,4 @@ class Plant: return True elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE: return True - return False - @staticmethod - def get_closest_mature_plant(map1, tractor1): #TO DO, pobiera współrzędne najbliższej dojrzałej rośliny od miejsca, w którym znajduje się traktor - 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): - 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() > 0 and field.get_plant().get_state() < definitions.BEETROOTS_MAXIMUM_STATE: - field.get_plant().set_state(field.get_plant().get_state() + 1) - elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() < definitions.CARROTS_MAXIMUM_STATE: - field.get_plant().set_state(field.get_plant().get_state() + 1) - elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() > 0 and field.get_plant().get_state() < definitions.POTATOES_MAXIMUM_STATE: - field.get_plant().set_state(field.get_plant().get_state() + 1) - elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() > 0 and field.get_plant().get_state() < definitions.WHEAT_MAXIMUM_STATE: - field.get_plant().set_state(field.get_plant().get_state() + 1) \ No newline at end of file + return False \ No newline at end of file diff --git a/py.py b/py.py index 0220af9..e3b3590 100644 --- a/py.py +++ b/py.py @@ -1,47 +1,48 @@ import astar +import cart import definitions import graph import map +import neuralnetwork import plant import pygame import station import treelearn -import tractor -pygame.display.set_caption("Smart Tractor") +pygame.display.set_caption("Smart Cart") 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} + amount_of_seeds_dict = {"beetroot": definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE, "carrot": definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE, "potato": definitions.CART_AMOUNT_OF_SEEDS_EACH_TYPE, "wheat": definitions.CART_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} + fertilizer_dict = {"beetroot": definitions.CART_FERTILIZER, "carrot": definitions.CART_FERTILIZER, "potato": definitions.CART_FERTILIZER, "wheat": definitions.CART_FERTILIZER} station1 = station.Station(collected_plants_dict) - 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) + cart1 = cart.Cart(amount_of_seeds_dict, collected_plants_dict, definitions.CART_DIRECTION_NORTH, fertilizer_dict, definitions.CART_FUEL, definitions.CART_WATER_LEVEL, 0, 0) + cart1_rect = pygame.Rect(cart1.get_x(), cart1.get_y(), definitions.BLOCK_SIZE, definitions.BLOCK_SIZE) clock = pygame.time.Clock() tree = treelearn.treelearn() #tworzenie drzewa decyzyjnego decision = [0] #początkowa decyzja o braku powrotu do stacji (0) + #neuralnetwork.create_neural_network() run = True while run: #pętla główna programu clock.tick(definitions.FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False - map1.draw_window(tractor1, tractor1_rect) + map1.draw_window(cart1, cart1_rect) 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 + istate = graph.Istate(cart1.get_direction(), cart1.get_x() / definitions.BLOCK_SIZE, cart1.get_y() / definitions.BLOCK_SIZE) #stan początkowy wózka (jego orientacja oraz jego aktualne współrzędne) if decision == [0]: #jeżeli decyzja jest 0 (brak powrotu do stacji) to uprawiaj pole - 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 + move_list = (astar.graphsearch([], [], istate, graph.succ, plant.Plant.get_mature_plant(map1, istate), astar.f, map1)) #lista z ruchami, które należy po kolei wykonać, astar else: #jeżeli decyzja jest 1 (powrót do stacji) to wróć do stacji uzupełnić zapasy move_list = (graph.graphsearch([], [], istate, graph.succ, (0, 0))) #lista z ruchami, które należy po kolei wykonać, graphsearch 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 + cart1.handle_movement(move_list.pop(0), cart1_rect) #wykonaj kolejny ruch oraz zdejmij ten ruch z początku listy else: - tractor1.handle_random_movement(tractor1_rect) #wykonuj losowe ruchy - tractor1.do_work(map1, station1, tractor1_rect) #wykonaj pracę na danym polu - decision = treelearn.make_decision(tree, tractor1.get_all_amount_of_seeds(), tractor1.get_all_collected_plants(), tractor1.get_all_fertilizer(), tractor1.get_fuel(), tractor1.get_water_level()) #podejmij decyzję czy wracać do stacji (0 : NIE, 1 : TAK) + cart1.handle_movement_random(cart1_rect) #wykonuj losowe ruchy + cart1.do_work(map1, station1, cart1_rect) #wykonaj pracę na danym polu + decision = treelearn.make_decision(tree, cart1.get_all_amount_of_seeds(), cart1.get_all_collected_plants(), cart1.get_all_fertilizer(), cart1.get_fuel(), cart1.get_water_level()) #podejmij decyzję czy wracać do stacji (0 : NIE, 1 : TAK) plant.Plant.grow_plants(map1) #zwiększ poziom dojrzałości roślin pygame.quit() if __name__ == "__main__": diff --git a/resources/data.csv b/resources/decision_tree/data.csv similarity index 100% rename from resources/data.csv rename to resources/decision_tree/data.csv diff --git a/resources/mytree.png b/resources/decision_tree/mytree.png similarity index 100% rename from resources/mytree.png rename to resources/decision_tree/mytree.png diff --git a/resources/tree.pkl b/resources/decision_tree/tree.pkl similarity index 100% rename from resources/tree.pkl rename to resources/decision_tree/tree.pkl diff --git a/resources/beetroots_stage_0.png b/resources/images/beetroots_stage_0.png similarity index 100% rename from resources/beetroots_stage_0.png rename to resources/images/beetroots_stage_0.png diff --git a/resources/beetroots_stage_1.png b/resources/images/beetroots_stage_1.png similarity index 100% rename from resources/beetroots_stage_1.png rename to resources/images/beetroots_stage_1.png diff --git a/resources/beetroots_stage_2.png b/resources/images/beetroots_stage_2.png similarity index 100% rename from resources/beetroots_stage_2.png rename to resources/images/beetroots_stage_2.png diff --git a/resources/beetroots_stage_3.png b/resources/images/beetroots_stage_3.png similarity index 100% rename from resources/beetroots_stage_3.png rename to resources/images/beetroots_stage_3.png diff --git a/resources/carrots_stage_0.png b/resources/images/carrots_stage_0.png similarity index 100% rename from resources/carrots_stage_0.png rename to resources/images/carrots_stage_0.png diff --git a/resources/carrots_stage_1.png b/resources/images/carrots_stage_1.png similarity index 100% rename from resources/carrots_stage_1.png rename to resources/images/carrots_stage_1.png diff --git a/resources/carrots_stage_2.png b/resources/images/carrots_stage_2.png similarity index 100% rename from resources/carrots_stage_2.png rename to resources/images/carrots_stage_2.png diff --git a/resources/carrots_stage_3.png b/resources/images/carrots_stage_3.png similarity index 100% rename from resources/carrots_stage_3.png rename to resources/images/carrots_stage_3.png diff --git a/resources/dirt.png b/resources/images/dirt.png similarity index 100% rename from resources/dirt.png rename to resources/images/dirt.png diff --git a/resources/farmland_dry.png b/resources/images/farmland_dry.png similarity index 100% rename from resources/farmland_dry.png rename to resources/images/farmland_dry.png diff --git a/resources/farmland_wet.png b/resources/images/farmland_wet.png similarity index 100% rename from resources/farmland_wet.png rename to resources/images/farmland_wet.png diff --git a/resources/flower_dandelion.png b/resources/images/flower_dandelion.png similarity index 100% rename from resources/flower_dandelion.png rename to resources/images/flower_dandelion.png diff --git a/resources/minecart_command_block_east.png b/resources/images/minecart_command_block_east.png similarity index 100% rename from resources/minecart_command_block_east.png rename to resources/images/minecart_command_block_east.png diff --git a/resources/minecart_command_block_north.png b/resources/images/minecart_command_block_north.png similarity index 100% rename from resources/minecart_command_block_north.png rename to resources/images/minecart_command_block_north.png diff --git a/resources/minecart_command_block_south.png b/resources/images/minecart_command_block_south.png similarity index 100% rename from resources/minecart_command_block_south.png rename to resources/images/minecart_command_block_south.png diff --git a/resources/minecart_command_block_west.png b/resources/images/minecart_command_block_west.png similarity index 100% rename from resources/minecart_command_block_west.png rename to resources/images/minecart_command_block_west.png diff --git a/resources/potatoes_stage_0.png b/resources/images/potatoes_stage_0.png similarity index 100% rename from resources/potatoes_stage_0.png rename to resources/images/potatoes_stage_0.png diff --git a/resources/potatoes_stage_1.png b/resources/images/potatoes_stage_1.png similarity index 100% rename from resources/potatoes_stage_1.png rename to resources/images/potatoes_stage_1.png diff --git a/resources/potatoes_stage_2.png b/resources/images/potatoes_stage_2.png similarity index 100% rename from resources/potatoes_stage_2.png rename to resources/images/potatoes_stage_2.png diff --git a/resources/potatoes_stage_3.png b/resources/images/potatoes_stage_3.png similarity index 100% rename from resources/potatoes_stage_3.png rename to resources/images/potatoes_stage_3.png diff --git a/resources/rail_normal.png b/resources/images/rail_normal.png similarity index 100% rename from resources/rail_normal.png rename to resources/images/rail_normal.png diff --git a/resources/sponge.png b/resources/images/sponge.png similarity index 100% rename from resources/sponge.png rename to resources/images/sponge.png diff --git a/resources/wheat_stage_0.png b/resources/images/wheat_stage_0.png similarity index 100% rename from resources/wheat_stage_0.png rename to resources/images/wheat_stage_0.png diff --git a/resources/wheat_stage_1.png b/resources/images/wheat_stage_1.png similarity index 100% rename from resources/wheat_stage_1.png rename to resources/images/wheat_stage_1.png diff --git a/resources/wheat_stage_2.png b/resources/images/wheat_stage_2.png similarity index 100% rename from resources/wheat_stage_2.png rename to resources/images/wheat_stage_2.png diff --git a/resources/wheat_stage_3.png b/resources/images/wheat_stage_3.png similarity index 100% rename from resources/wheat_stage_3.png rename to resources/images/wheat_stage_3.png diff --git a/resources/wheat_stage_4.png b/resources/images/wheat_stage_4.png similarity index 100% rename from resources/wheat_stage_4.png rename to resources/images/wheat_stage_4.png diff --git a/resources/wheat_stage_5.png b/resources/images/wheat_stage_5.png similarity index 100% rename from resources/wheat_stage_5.png rename to resources/images/wheat_stage_5.png diff --git a/resources/wheat_stage_6.png b/resources/images/wheat_stage_6.png similarity index 100% rename from resources/wheat_stage_6.png rename to resources/images/wheat_stage_6.png diff --git a/resources/wheat_stage_7.png b/resources/images/wheat_stage_7.png similarity index 100% rename from resources/wheat_stage_7.png rename to resources/images/wheat_stage_7.png diff --git a/treelearn.py b/treelearn.py index 0168fc8..249d7bf 100644 --- a/treelearn.py +++ b/treelearn.py @@ -6,24 +6,24 @@ import pickle import pydotplus from sklearn import tree from sklearn.tree import DecisionTreeClassifier +def make_decision(tree, amount_of_seeds, collected_plants, fertilizer, fuel, water_level): #zwraca decyzję o powrocie do stacji (0 : NIE, 1 : TAK) + decision = tree.predict([[amount_of_seeds, collected_plants, fertilizer, fuel, water_level]]) #podejmij decyzję na podstawie aktualnych parametrów wózka o powrocie do stacji lub nie + return decision def treelearn(): #zwraca utworzone drzewo decyzyjne - if os.path.exists("resources/tree.pkl"): #jeżeli drzewo jest zapisane w pliku to odczytaj - dtree = pickle.load(open(os.path.join('resources', "tree.pkl"), "rb")) + if os.path.exists("resources/decision_tree/tree.pkl"): #jeżeli drzewo jest zapisane w pliku to odczytaj + dtree = pickle.load(open(os.path.join('resources/decision_tree', "tree.pkl"), "rb")) else: #w przeciwnym razie utwórz drzewo od początku i zapisz do pliku - df = pandas.read_csv(os.path.join('resources', 'data.csv')) #czytanie danych do nauki drzewa z pliku .csv + df = pandas.read_csv(os.path.join('resources/decision_tree', 'data.csv')) #czytanie danych do nauki drzewa z pliku .csv features = ['amount of seeds', 'collected plants', 'fertilizer', 'fuel', 'water level'] x = df[features] #wczytanie atrybutów, z których ma się uczyć drzewo y = df['back to station'] #podjęte decyzje dtree = DecisionTreeClassifier() #klasyfikuje drzewo dtree = dtree.fit(x, y) #uczy drzewo - pickle.dump(dtree, open(os.path.join('resources', "tree.pkl"), "wb")) + pickle.dump(dtree, open(os.path.join('resources/decision_tree', "tree.pkl"), "wb")) data = tree.export_graphviz(dtree, out_file=None, feature_names=features) graph = pydotplus.graph_from_dot_data(data) - graph.write_png(os.path.join('resources', 'mytree.png')) - img = pltimg.imread(os.path.join('resources', 'mytree.png')) + graph.write_png(os.path.join('resources/decision_tree', 'mytree.png')) + img = pltimg.imread(os.path.join('resources/decision_tree', 'mytree.png')) imgplot = plt.imshow(img) plt.show() #wyświetl drzewo decyzyjne - return dtree -def make_decision(tree, amount_of_seeds, collected_plants, fertilizer, fuel, water_level): #zwraca decyzję o powrocie do stacji (0 : NIE, 1 : TAK) - decision = tree.predict([[amount_of_seeds, collected_plants, fertilizer, fuel, water_level]]) #podejmij decyzję na podstawie aktualnych parametrów traktora o powrocie do stacji lub nie - return decision \ No newline at end of file + return dtree \ No newline at end of file