Compare commits

..

No commits in common. "92c893c917d425b59dec30da2adc7ac4904ef2e2" and "af15a1004844715dabd0c4c6b1c1f13b83cdcb6e" have entirely different histories.

8 changed files with 45 additions and 116 deletions

View File

@ -13,21 +13,13 @@ from Pole import stoneList
from queue import PriorityQueue from queue import PriorityQueue
def getRandomGoalTreasure():
while True:
goalTreasure = (random.randint(0, NUM_X - 1), random.randint(0, NUM_Y - 1)) # Współrzędne celu
if goalTreasure not in stoneList:
break
return goalTreasure
def heuristic(state, goal): def heuristic(state, goal):
# Oblicz odległość Manhattanowską między aktualnym stanem a celem # Oblicz odległość Manhattanowską między aktualnym stanem a celem
manhattan_distance = abs(state['x'] - goal[0]) + abs(state['y'] - goal[1]) manhattan_distance = abs(state['x'] - goal[0]) + abs(state['y'] - goal[1])
return manhattan_distance return manhattan_distance
'''def get_cost_for_plant(plant_name): def get_cost_for_plant(plant_name):
plant_costs = { plant_costs = {
"pszenica": 7, "pszenica": 7,
"kukurydza": 9, "kukurydza": 9,
@ -43,19 +35,14 @@ def heuristic(state, goal):
else: else:
# Jeśli nazwa rośliny nie istnieje w słowniku, zwróć domyślną wartość # Jeśli nazwa rośliny nie istnieje w słowniku, zwróć domyślną wartość
return 0 return 0
'''
def A_star(istate, pole, goalTreasure):
# goalTreasure = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1))
# #jeśli chcemy używać random musimy wykreslić sloty z kamieniami, ponieważ tez mogą się wylosować i wtedy traktor w ogóle nie rusza
#lub zrobić to jakoś inaczej, np. funkcja szukająca najmniej nawodnionej rośliny
# przeniesione wyżej do funkcji getRandomGoalTreasure, wykorzystywana jest w App.py
# while True:
# goalTreasure = (random.randint(0, NUM_X - 1), random.randint(0, NUM_Y - 1)) # Współrzędne celu
# if goalTreasure not in stoneList:
# break
def A_star(istate, pole):
#goalTreasure = (5, 5)
while True:
goalTreasure = (random.randint(0, NUM_X - 1), random.randint(0, NUM_Y - 1)) # Współrzędne celu
if goalTreasure not in stoneList:
break
fringe = PriorityQueue() # Kolejka priorytetowa dla wierzchołków do rozpatrzenia fringe = PriorityQueue() # Kolejka priorytetowa dla wierzchołków do rozpatrzenia
explored = [] # Lista odwiedzonych stanów explored = [] # Lista odwiedzonych stanów
obrot = 1 obrot = 1
@ -72,20 +59,20 @@ def A_star(istate, pole, goalTreasure):
if BFS.goalTest3(elem.state, goalTreasure): # Sprawdzenie, czy osiągnięto cel if BFS.goalTest3(elem.state, goalTreasure): # Sprawdzenie, czy osiągnięto cel
path = [] path = []
cost_list=[] total_cost = elem.g
print("Koszt", total_cost)
while elem.parent is not None: # Odtworzenie ścieżki while elem.parent is not None: # Odtworzenie ścieżki
path.append([elem.parent, elem.action]) path.append([elem.parent, elem.action])
elem = elem.parent elem = elem.parent
for node, action in path: for node, action in path:
# Obliczanie kosztu ścieżki dla każdego pola i wyświetlanie # Obliczanie kosztu ścieżki dla każdego pola i wyświetlanie
plant_cost = get_plant_name_and_cost_from_coordinates(node.state['x'],node.state['y'], pole) plant_name = get_plant_name_from_coordinates(node.state['x'], node.state['y'], pole)
plant_cost = get_cost_for_plant(plant_name)
if action == "left" or action == "right": # Liczenie kosztu tylko dla pól nie będących obrotami if action == "left" or action == "right": # Liczenie kosztu tylko dla pól nie będących obrotami
total_cost += obrot total_cost += obrot
cost_list.append(obrot)
else: else:
total_cost += plant_cost total_cost += plant_cost
cost_list.append(plant_cost) return path
return path,cost_list,total_cost
explored.append(elem.state) explored.append(elem.state)
@ -97,9 +84,9 @@ def A_star(istate, pole, goalTreasure):
child.action = resp[0] child.action = resp[0]
# Pobranie nazwy rośliny z danego slotu na podstawie współrzędnych # Pobranie nazwy rośliny z danego slotu na podstawie współrzędnych
plant_cost = get_plant_name_and_cost_from_coordinates(child_state['x'], child_state['y'], pole) plant_name = get_plant_name_from_coordinates(child_state['x'], child_state['y'], pole)
# Pobranie kosztu dla danej rośliny # Pobranie kosztu dla danej rośliny
#plant_cost = get_cost_for_plant(plant_name) plant_cost = get_cost_for_plant(plant_name)
if child.action == "left" or child.action == "right": if child.action == "left" or child.action == "right":
child.g = elem.g + obrot child.g = elem.g + obrot
@ -130,15 +117,15 @@ def A_star(istate, pole, goalTreasure):
return False return False
def get_plant_name_and_cost_from_coordinates(x, y, pole): def get_plant_name_from_coordinates(x, y, pole):
if (x, y) in pole.slot_dict: # Sprawdzenie, czy podane współrzędne znajdują się na polu if (x, y) in pole.slot_dict: # Sprawdzenie, czy podane współrzędne znajdują się na polu
slot = pole.slot_dict[(x, y)] # Pobranie slotu na podstawie współrzędnych slot = pole.slot_dict[(x, y)] # Pobranie slotu na podstawie współrzędnych
if slot.plant: # Sprawdzenie, czy na slocie znajduje się roślina if slot.plant: # Sprawdzenie, czy na slocie znajduje się roślina
return slot.plant.stan.koszt # Zwrócenie nazwy rośliny na slocie return slot.plant.nazwa # Zwrócenie nazwy rośliny na slocie
else: else:
return 0 # jeśli na slocie nie ma rośliny return None # jeśli na slocie nie ma rośliny
else: else:
return 0 # jeśli podane współrzędne są poza polem return None # jeśli podane współrzędne są poza polem
#to ogólnie identyczna funkcja jak w BFS ale nie chciałam tam ruszać, żeby przypadkiem nie zapsuć do BFS, #to ogólnie identyczna funkcja jak w BFS ale nie chciałam tam ruszać, żeby przypadkiem nie zapsuć do BFS,
@ -177,46 +164,32 @@ def heuristic2(state, goal):
return manhattan_distance return manhattan_distance
def A_star2(istate, pole, goalTreasure): def A_star2(istate, pole):
# goalTreasure = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1)) # goalTreasure = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1))
# #jeśli chcemy używać random musimy wykreslić sloty z kamieniami, ponieważ tez mogą się wylosować i wtedy traktor w ogóle nie rusza # #jeśli chcemy używać random musimy wykreslić sloty z kamieniami, ponieważ tez mogą się wylosować i wtedy traktor w ogóle nie rusza
#lub zrobić to jakoś inaczej, np. funkcja szukająca najmniej nawodnionej rośliny #lub zrobić to jakoś inaczej, np. funkcja szukająca najmniej nawodnionej rośliny
while True:
# przeniesione wyżej do funkcji getRandomGoalTreasure, wykorzystywana jest w App.py goalTreasure = (random.randint(0, NUM_X - 1), random.randint(0, NUM_Y - 1)) # Współrzędne celu
# while True: if goalTreasure not in stoneList:
# goalTreasure = (random.randint(0, NUM_X - 1), random.randint(0, NUM_Y - 1)) # Współrzędne celu break
# if goalTreasure not in stoneList:
# break
fringe = PriorityQueue() # Kolejka priorytetowa dla wierzchołków do rozpatrzenia fringe = PriorityQueue() # Kolejka priorytetowa dla wierzchołków do rozpatrzenia
explored = [] # Lista odwiedzonych stanów explored = [] # Lista odwiedzonych stanów
obrot = 1
# Tworzenie węzła początkowego # Tworzenie węzła początkowego
x = Node.Node(istate) x = Node.Node(istate)
x.g = 0 x.g = 0
x.h = heuristic2(x.state, goalTreasure) x.h = heuristic2(x.state, goalTreasure)
fringe.put((x.g + x.h, x)) # Dodanie węzła do kolejki fringe.put((x.g + x.h, x)) # Dodanie węzła do kolejki
total_cost=0
while not fringe.empty(): while not fringe.empty():
_, elem = fringe.get() # Pobranie węzła z najniższym priorytetem _, elem = fringe.get() # Pobranie węzła z najniższym priorytetem
if BFS.goalTest3(elem.state, goalTreasure): # Sprawdzenie, czy osiągnięto cel if BFS.goalTest3(elem.state, goalTreasure): # Sprawdzenie, czy osiągnięto cel
path = [] path = []
cost_list=[]
while elem.parent is not None: # Odtworzenie ścieżki while elem.parent is not None: # Odtworzenie ścieżki
path.append([elem.parent, elem.action]) path.append([elem.parent, elem.action])
elem = elem.parent elem = elem.parent
for node, action in path: return path
# Obliczanie kosztu ścieżki dla każdego pola i wyświetlanie
plant_cost = get_plant_name_and_cost_from_coordinates(node.state['x'],node.state['y'], pole)
if action == "left" or action == "right": # Liczenie kosztu tylko dla pól nie będących obrotami
total_cost += obrot
cost_list.append(obrot)
else:
total_cost += plant_cost
cost_list.append(plant_cost)
return path,cost_list,total_cost
explored.append(elem.state) explored.append(elem.state)
@ -228,12 +201,12 @@ def A_star2(istate, pole, goalTreasure):
child.action = resp[0] child.action = resp[0]
# Pobranie nazwy rośliny z danego slotu na podstawie współrzędnych # Pobranie nazwy rośliny z danego slotu na podstawie współrzędnych
plant_cost = get_plant_name_and_cost_from_coordinates(child_state['x'], child_state['y'], pole) plant_name = get_plant_name_from_coordinates(child_state['x'], child_state['y'], pole)
# Pobranie kosztu dla danej rośliny
plant_cost = get_cost_for_plant(plant_name)
if child.action == "left" or child.action == "right": # Obliczenie kosztu ścieżki dla dziecka
child.g = elem.g + obrot child.g = elem.g + plant_cost
else:
child.g = elem.g + plant_cost
# Obliczenie heurystyki dla dziecka # Obliczenie heurystyki dla dziecka
child.h = heuristic2(child.state, goalTreasure) child.h = heuristic2(child.state, goalTreasure)

38
App.py
View File

@ -9,14 +9,13 @@ import Osprzet
import Ui import Ui
import BFS import BFS
import AStar import AStar
import random
bfs1_flag=False bfs1_flag=False
bfs2_flag=False #Change this lines to show different bfs implementation bfs2_flag=False #Change this lines to show different bfs implementation
bfs3_flag=False bfs3_flag=False
Astar = True Astar = False
Astar2 = False Astar2 = True
if bfs3_flag or Astar or Astar2: if bfs3_flag or Astar or Astar2:
Pole.stoneFlag = True Pole.stoneFlag = True
@ -28,8 +27,7 @@ FPS=5
clock=pygame.time.Clock() clock=pygame.time.Clock()
image_loader=Image.Image() image_loader=Image.Image()
image_loader.load_images() image_loader.load_images()
goalTreasure = AStar.getRandomGoalTreasure() # nie wiem czy to najlepsze miejsce, obecnie pole zawiera pole gasStation, które służy do renderowania odpowiedniego zdjęcia pole=Pole.Pole(screen,image_loader)
pole=Pole.Pole(screen,image_loader, goalTreasure)
pole.draw_grid() #musi byc tutaj wywołane ponieważ inicjalizuje sloty do slownika pole.draw_grid() #musi byc tutaj wywołane ponieważ inicjalizuje sloty do slownika
ui=Ui.Ui(screen) ui=Ui.Ui(screen)
#Tractor creation #Tractor creation
@ -79,38 +77,24 @@ def init_demo(): #Demo purpose
print_to_console("Traktor porusza sie obliczona sciezka BFS") print_to_console("Traktor porusza sie obliczona sciezka BFS")
traktor.move_by_root(bfsRoot3, pole, [traktor.irrigateSlot]) traktor.move_by_root(bfsRoot3, pole, [traktor.irrigateSlot])
if (Astar): if (Astar):
aStarRoot,cost_list,total_cost= AStar.A_star({'x': 0, 'y': 0, 'direction': "E"}, pole, goalTreasure) aStarRoot = AStar.A_star({'x': 0, 'y': 0, 'direction': "E"}, pole)
if aStarRoot: if aStarRoot:
print("Pełna ścieżka agenta:") #print("Pełna ścieżka agenta:")
aStarRoot.reverse() aStarRoot.reverse()
cost_list.reverse() #for node in aStarRoot:
i=0 # state = node[0].state # Pobranie stanu z obiektu Node
for node in aStarRoot: # action = node[1] # Pobranie akcji
state = node[0].state # Pobranie stanu z obiektu Node # print("Współrzędne pola:", state['x'], state['y'], "- Akcja:",action) # wypisuje ścieżkę i kroki które robi traktor
action = node[1] # Pobranie akcji
print("Współrzędne pola:", state['x'], state['y'], "- Akcja:",action,"- Koszt: ",cost_list[i])
i=i+1
print_to_console("Traktor porusza się obliczoną ścieżką A*") print_to_console("Traktor porusza się obliczoną ścieżką A*")
traktor.move_by_root(aStarRoot, pole, [traktor.irrigateSlot]) traktor.move_by_root(aStarRoot, pole, [traktor.irrigateSlot])
print("Koszt:", total_cost)
else: else:
print_to_console("Nie można znaleźć ścieżki A*") # Wyświetl komunikat, jeśli nie znaleziono ścieżki print_to_console("Nie można znaleźć ścieżki A*") # Wyświetl komunikat, jeśli nie znaleziono ścieżki
if (Astar2): if (Astar2):
aStarRoot2 = AStar.A_star2({'x': 0, 'y': 0, 'direction': "E"}, pole)
aStarRoot2,cost_list= AStar.A_star2({'x': 0, 'y': 0, 'direction': "E"}, pole, goalTreasure)
if aStarRoot2: if aStarRoot2:
print("Pełna ścieżka agenta:")
aStarRoot2.reverse() aStarRoot2.reverse()
cost_list.reverse()
i=0
for node in aStarRoot2:
state = node[0].state # Pobranie stanu z obiektu Node
action = node[1] # Pobranie akcji
print("Współrzędne pola:", state['x'], state['y'], "- Akcja:",action,"- Koszt: ",cost_list[i])
i=i+1
print_to_console("Traktor porusza się obliczoną ścieżką A*") print_to_console("Traktor porusza się obliczoną ścieżką A*")
traktor.move_by_root(aStarRoot2, pole, [traktor.irrigateSlot]) traktor.move_by_root(aStarRoot2, pole, [traktor.irrigateSlot])
print("Koszt:", total_cost)
else: else:
print_to_console("Nie można znaleźć ścieżki A*") # Wyświetl komunikat, jeśli nie znaleziono ścieżki print_to_console("Nie można znaleźć ścieżki A*") # Wyświetl komunikat, jeśli nie znaleziono ścieżki
@ -152,5 +136,3 @@ def get_info(old_info):

View File

@ -8,18 +8,15 @@ class Image:
self.tractor_image=None self.tractor_image=None
self.garage_image=None self.garage_image=None
self.stone_image=None self.stone_image=None
self.gasStation_image=None
def load_images(self): def load_images(self):
files_plants={ files_plants={0:"borowka",
0:"borowka",
1:"kukurydza", 1:"kukurydza",
2:"pszenica", 2:"pszenica",
3:"slonecznik", 3:"slonecznik",
4:"winogrono", 4:"winogrono",
5:"ziemniak", 5:"ziemniak",
6:"dirt", 6:"dirt",
7:"mud", 7:"mud"}
8:"road"}
for index in files_plants: for index in files_plants:
if index >= 6: if index >= 6:
plant_image = pygame.image.load("images/" + files_plants[index] + ".jpg") plant_image = pygame.image.load("images/" + files_plants[index] + ".jpg")
@ -33,8 +30,6 @@ class Image:
self.garage_image=pygame.transform.scale(garage,(dCon.CUBE_SIZE,dCon.CUBE_SIZE)) self.garage_image=pygame.transform.scale(garage,(dCon.CUBE_SIZE,dCon.CUBE_SIZE))
stone=pygame.image.load("images/stone.png") stone=pygame.image.load("images/stone.png")
self.stone_image=pygame.transform.scale(stone,(dCon.CUBE_SIZE,dCon.CUBE_SIZE)) self.stone_image=pygame.transform.scale(stone,(dCon.CUBE_SIZE,dCon.CUBE_SIZE))
gasStation=pygame.image.load("images/gasStation.png")
self.gasStation_image=pygame.transform.scale(gasStation,(dCon.CUBE_SIZE,dCon.CUBE_SIZE))
def return_random_plant(self): def return_random_plant(self):
x=random.randint(0,7) x=random.randint(0,7)
@ -50,6 +45,3 @@ class Image:
def return_stone(self): def return_stone(self):
return self.stone_image return self.stone_image
def return_gasStation(self):
return self.gasStation_image

11
Pole.py
View File

@ -5,18 +5,16 @@ import pygame
import time import time
import Ui import Ui
import math import math
import random
stoneList = [(3,3), (3,4), (3,5), (3,6), (4,6), (5,6), (6,6), (7,6), (8,6), (9,6), (10,6), (11,6), (12,6), (13,6), (14,6), (15,6), (16,6), (16,7), (16,8), (16,9)] stoneList = [(3,3), (3,4), (3,5), (3,6), (4,6), (5,6), (6,6), (7,6), (8,6), (9,6), (10,6), (11,6), (12,6), (13,6), (14,6), (15,6), (16,6), (16,7), (16,8), (16,9)]
stoneFlag = False stoneFlag = False
class Pole: class Pole:
def __init__(self,screen,image_loader, gasStation = (-1, -1)): def __init__(self,screen,image_loader):
self.screen=screen self.screen=screen
self.slot_dict={} #Slot are stored in dictionary with key being a Tuple of x and y coordinates so top left slot key is (0,0) and value is slot object self.slot_dict={} #Slot are stored in dictionary with key being a Tuple of x and y coordinates so top left slot key is (0,0) and value is slot object
self.ui=Ui.Ui(screen) self.ui=Ui.Ui(screen)
self.image_loader=image_loader self.image_loader=image_loader
self.gasStation=gasStation
def get_slot_from_cord(self,coordinates): def get_slot_from_cord(self,coordinates):
(x_axis,y_axis)=coordinates (x_axis,y_axis)=coordinates
@ -44,16 +42,13 @@ class Pole:
for i in stoneList: for i in stoneList:
st=self.slot_dict[i] st=self.slot_dict[i]
st.set_stone_image() st.set_stone_image()
if self.gasStation[0] != -1:
st=self.slot_dict[self.gasStation]
st.set_gasStation_image()
def randomize_colors(self): def randomize_colors(self):
pygame.display.update() pygame.display.update()
time.sleep(3) time.sleep(3)
#self.ui.render_text("Randomizing Crops") #self.ui.render_text("Randomizing Crops")
for coordinates in self.slot_dict: for coordinates in self.slot_dict:
if(coordinates==(0,0) or coordinates in stoneList or coordinates == self.gasStation): if(coordinates==(0,0) or coordinates in stoneList):
continue continue
else: else:
self.slot_dict[coordinates].set_random_plant() self.slot_dict[coordinates].set_random_plant()
@ -77,5 +72,3 @@ class Pole:
collided=self.get_slot_from_cord((mouse_x,mouse_y)) collided=self.get_slot_from_cord((mouse_x,mouse_y))
return collided.print_status() return collided.print_status()
return "" return ""

12
Slot.py
View File

@ -23,12 +23,7 @@ class Slot:
pygame.display.update() pygame.display.update()
def redraw_image(self): def redraw_image(self):
self.mark_visited() self.set_image()
def mark_visited(self):
plant,self.plant_image=self.image_loader.return_plant('road')
self.screen.blit(self.plant_image, (self.x_axis * dCon.CUBE_SIZE, self.y_axis * dCon.CUBE_SIZE))
pygame.draw.rect(self.screen, Colors.BLACK, self.field, BORDER_THICKNESS)
def color_change(self,color): def color_change(self,color):
self.plant=color self.plant=color
@ -55,11 +50,6 @@ class Slot:
self.screen.blit(self.plant_image, (self.x_axis * dCon.CUBE_SIZE, self.y_axis * dCon.CUBE_SIZE)) self.screen.blit(self.plant_image, (self.x_axis * dCon.CUBE_SIZE, self.y_axis * dCon.CUBE_SIZE))
pygame.draw.rect(self.screen, Colors.BLACK, self.field, BORDER_THICKNESS) pygame.draw.rect(self.screen, Colors.BLACK, self.field, BORDER_THICKNESS)
def set_gasStation_image(self):
self.plant_image=self.image_loader.return_gasStation()
self.screen.blit(self.plant_image, (self.x_axis * dCon.CUBE_SIZE, self.y_axis * dCon.CUBE_SIZE))
pygame.draw.rect(self.screen, Colors.BLACK, self.field, BORDER_THICKNESS)
def random_plant(self): #Probably will not be used later only for demo purpouse def random_plant(self): #Probably will not be used later only for demo purpouse
return self.image_loader.return_random_plant() return self.image_loader.return_random_plant()

1
Ui.py
View File

@ -25,7 +25,6 @@ class Ui:
def render_text_to_console(self,string_to_print): def render_text_to_console(self,string_to_print):
font=pygame.font.Font(self.font,self.font_size) font=pygame.font.Font(self.font,self.font_size)
string_to_print=str(string_to_print)
self.break_string_to_console(string_to_print) self.break_string_to_console(string_to_print)
for string in self.to_print: for string in self.to_print:
text=font.render(string,True,Colors.BLACK,Colors.WHITE) text=font.render(string,True,Colors.BLACK,Colors.WHITE)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB