Merge pull request 'New surfaces were made (mud, dirt, stone).' (#18) from introduction_astar into astar

Reviewed-on: #18
This commit is contained in:
s481834 2024-04-25 20:51:56 +02:00
commit 2017b89aa4
13 changed files with 111 additions and 41 deletions

6
AStar.py Normal file
View File

@ -0,0 +1,6 @@
"""
f(n) = g(n) + h(n)
g(n) = dotychczasowy koszt -> dodać currentCost w Node lub brać koszt na nowo przy oddtawrzaniu ścieżki
h(n) = abs(state['x'] - goalTreassure[0]) + abs(state['y'] - goalTreassure[1]) -> odległość Manhatan -> można zrobić jeszcze drugą wersje gdzie mnoży się razy 5.5 ze wzgledu na średni koszt przejścia
Należy zaimplementować kolejkę priorytetową oraz zaimplementować algorytm przeszukiwania grafu stanów z uwzględnieniem kosztu za pomocą przerobienia algorytmu przeszukiwania grafu stanów
"""

16
App.py
View File

@ -10,6 +10,12 @@ import Ui
import BFS import BFS
bfs1_flag=False
bfs2_flag=False #Change this lines to show different bfs implementation
bfs3_flag=True
if bfs3_flag:
Pole.stoneFlag = True
pygame.init() pygame.init()
show_console=True show_console=True
screen = pygame.display.set_mode((dCon.getScreenWidth(show_console), dCon.getScreenHeihgt())) screen = pygame.display.set_mode((dCon.getScreenWidth(show_console), dCon.getScreenHeihgt()))
@ -21,9 +27,6 @@ pole=Pole.Pole(screen,image_loader)
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
bfs1_flag=True
bfs2_flag=False #Change this lines to show different bfs implementation
bfs3_flag=False
traktor_slot = pole.get_slot_from_cord((0, 0)) traktor_slot = pole.get_slot_from_cord((0, 0))
traktor = Tractor.Tractor(traktor_slot, screen, Osprzet.opryskiwacz,clock,bfs2_flag) traktor = Tractor.Tractor(traktor_slot, screen, Osprzet.opryskiwacz,clock,bfs2_flag)
@ -39,7 +42,10 @@ def init_demo(): #Demo purpose
clock.tick(FPS) clock.tick(FPS)
if(start_flag): if(start_flag):
ui.render_text_to_console(string_to_print="Przejazd inicjalizujacy- traktor sprawdza poziom nawodnienia") ui.render_text_to_console(string_to_print="Przejazd inicjalizujacy- traktor sprawdza poziom nawodnienia")
traktor.initial_move(pole) if not bfs1_flag:
time.sleep(2)
else:
traktor.initial_move(pole)
traktor.reset_pos(pole) traktor.reset_pos(pole)
clock.tick(20) clock.tick(20)
ui.clear_console() ui.clear_console()
@ -61,7 +67,7 @@ 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(bfsRoot2, pole, [traktor.irrigateSlot]) traktor.move_by_root(bfsRoot2, pole, [traktor.irrigateSlot])
if(bfs3_flag): if(bfs3_flag):
bfsRoot3 = BFS.BFS2({'x': 0, 'y': 0, 'direction': "E"}) bfsRoot3 = BFS.BFS3({'x': 0, 'y': 0, 'direction': "E"})
#displayControler: NUM_X: 20, NUM_Y: 12 (skarb) CHANGE THIS IN DCON BY HAND!!!!!!!! #displayControler: NUM_X: 20, NUM_Y: 12 (skarb) CHANGE THIS IN DCON BY HAND!!!!!!!!
bfsRoot3.reverse() bfsRoot3.reverse()
print_to_console("Traktor porusza sie obliczona sciezka BFS") print_to_console("Traktor porusza sie obliczona sciezka BFS")

23
BFS.py
View File

@ -3,6 +3,7 @@ import random
import pygame import pygame
import Node import Node
from displayControler import NUM_X, NUM_Y from displayControler import NUM_X, NUM_Y
from Pole import stoneList
def goalTest1(hIndex): def goalTest1(hIndex):
@ -93,31 +94,31 @@ def BFS1(istate):
def goalTest2(state, goalTreassure): def goalTest3(state, goalTreassure):
if state["x"] == goalTreassure[0] and state["y"] == goalTreassure[1]: if state["x"] == goalTreassure[0] and state["y"] == goalTreassure[1]:
return True return True
return False return False
def succ2(state): def succ3(state):
resp = [] resp = []
if state["direction"] == "N": if state["direction"] == "N":
if state["y"] > 0: if state["y"] > 0 and (state['x'], state["y"] - 1) not in stoneList:
resp.append(["forward", {'x': state["x"], 'y': state["y"]-1, 'direction': state["direction"]}]) resp.append(["forward", {'x': state["x"], 'y': state["y"]-1, 'direction': state["direction"]}])
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "E"}]) resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "E"}])
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "W"}]) resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "W"}])
elif state["direction"] == "S": elif state["direction"] == "S":
if state["y"] < NUM_Y: if state["y"] < NUM_Y and (state['x'], state["y"] + 1) not in stoneList:
resp.append(["forward", {'x': state["x"], 'y': state["y"]+1, 'direction': state["direction"]}]) resp.append(["forward", {'x': state["x"], 'y': state["y"]+1, 'direction': state["direction"]}])
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "W"}]) resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "W"}])
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "E"}]) resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "E"}])
elif state["direction"] == "E": elif state["direction"] == "E":
if state["x"] < NUM_X: if state["x"] < NUM_X and (state['x'] + 1, state["y"]) not in stoneList:
resp.append(["forward", {'x': state["x"]+1, 'y': state["y"], 'direction': state["direction"]}]) resp.append(["forward", {'x': state["x"]+1, 'y': state["y"], 'direction': state["direction"]}])
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "S"}]) resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "S"}])
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "N"}]) resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "N"}])
else: #state["zwrot"] == "W" else: #state["zwrot"] == "W"
if state["x"] > 0: if state["x"] > 0 and (state['x'] - 1, state["y"]) not in stoneList:
resp.append(["forward", {'x': state["x"]-1, 'y': state["y"], 'direction': state["direction"]}]) resp.append(["forward", {'x': state["x"]-1, 'y': state["y"], 'direction': state["direction"]}])
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "N"}]) resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "N"}])
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "S"}]) resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "S"}])
@ -125,14 +126,14 @@ def succ2(state):
return resp return resp
def check2(tab, state): def check3(tab, state):
for i in tab: for i in tab:
if i.state == state: if i.state == state:
return False return False
return True return True
def BFS2(istate): def BFS3(istate):
goalTreassuere = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1)) goalTreassuere = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1))
print(goalTreassuere) print(goalTreassuere)
fringe = [] fringe = []
@ -148,7 +149,7 @@ def BFS2(istate):
elem = fringe.pop(0) elem = fringe.pop(0)
if goalTest2(elem.state, goalTreassuere): if goalTest3(elem.state, goalTreassuere):
x = elem x = elem
tab = [] tab = []
while x.parent != None: while x.parent != None:
@ -158,8 +159,8 @@ def BFS2(istate):
explored.append(elem) explored.append(elem)
for resp in succ2(elem.state): for resp in succ3(elem.state):
if check2(fringe, resp[1]) and check2(explored, resp[1]): if check3(fringe, resp[1]) and check3(explored, resp[1]):
x = Node.Node(resp[1]) x = Node.Node(resp[1])
x.parent = elem x.parent = elem
x.action = resp[0] x.action = resp[0]

View File

@ -7,23 +7,32 @@ class Image:
self.plants_image_dict={} self.plants_image_dict={}
self.tractor_image=None self.tractor_image=None
self.garage_image=None self.garage_image=None
self.stone_image=None
def load_images(self): def load_images(self):
files_plants={0:"borowka", files_plants={0:"borowka",
1:"kukurydza", 1:"kukurydza",
2:"pszenica", 2:"pszenica",
3:"slonecznik", 3:"slonecznik",
4:"winogrono", 4:"winogrono",
5:"ziemniak"} 5:"ziemniak",
6:"dirt",
7:"mud"}
for index in files_plants: for index in files_plants:
plant_image=pygame.image.load("images/plants/"+files_plants[index]+".jpg") if index >= 6:
plant_image = pygame.image.load("images/" + files_plants[index] + ".jpg")
else:
plant_image=pygame.image.load("images/plants/"+files_plants[index]+".jpg")
plant_image=pygame.transform.scale(plant_image,(dCon.CUBE_SIZE,dCon.CUBE_SIZE)) plant_image=pygame.transform.scale(plant_image,(dCon.CUBE_SIZE,dCon.CUBE_SIZE))
self.plants_image_dict[files_plants[index]]=plant_image self.plants_image_dict[files_plants[index]]=plant_image
tractor_image=pygame.image.load("images/traktor.png") tractor_image=pygame.image.load("images/traktor.png")
tractor_image=pygame.transform.scale(tractor_image,(dCon.CUBE_SIZE,dCon.CUBE_SIZE)) tractor_image=pygame.transform.scale(tractor_image,(dCon.CUBE_SIZE,dCon.CUBE_SIZE))
garage=pygame.image.load("images/garage.png") garage=pygame.image.load("images/garage.png")
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")
self.stone_image=pygame.transform.scale(stone,(dCon.CUBE_SIZE,dCon.CUBE_SIZE))
def return_random_plant(self): def return_random_plant(self):
x=random.randint(0,5) x=random.randint(0,7)
keys=list(self.plants_image_dict.keys()) keys=list(self.plants_image_dict.keys())
plant=keys[x] plant=keys[x]
return (plant,self.plants_image_dict[plant]) return (plant,self.plants_image_dict[plant])
@ -32,4 +41,7 @@ class Image:
return (plant_name,self.plants_image_dict[plant_name]) return (plant_name,self.plants_image_dict[plant_name])
def return_garage(self): def return_garage(self):
return self.garage_image return self.garage_image
def return_stone(self):
return self.stone_image

13
Pole.py
View File

@ -6,6 +6,9 @@ import time
import Ui import Ui
import math import math
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
class Pole: class Pole:
def __init__(self,screen,image_loader): def __init__(self,screen,image_loader):
self.screen=screen self.screen=screen
@ -23,7 +26,7 @@ class Pole:
def get_slot_dict(self): #returns whole slot_dict def get_slot_dict(self): #returns whole slot_dict
return self.slot_dict return self.slot_dict
#Draw grid and tractor (new one) #Draw grid and tractor (new one)
def draw_grid(self): def draw_grid(self):
for x in range(0,dCon.NUM_X): #Draw all cubes in X axis for x in range(0,dCon.NUM_X): #Draw all cubes in X axis
@ -35,13 +38,17 @@ class Pole:
slot_dict[coordinates].draw() slot_dict[coordinates].draw()
garage=self.slot_dict[(0,0)] garage=self.slot_dict[(0,0)]
garage.set_garage_image() garage.set_garage_image()
if stoneFlag:
for i in stoneList:
st=self.slot_dict[i]
st.set_stone_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)): 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()

View File

@ -32,20 +32,49 @@ class Roslina:
- słonecznik: +3 - słonecznik: +3
- borówka: +5 - borówka: +5
- winogrono: +4 - winogrono: +4
"""
Koszt (0-15):
- pszenica: 7
- kukurydza: 9
- ziemniak: 2
- słonecznik: 5
- borówka: 3
- winogrono: 4
- szuter (ścieżka): 0
- błoto: 15
def __init__(self, nazwa, stan, srodek): def __init__(self, nazwa, stan, srodek):
self.nazwa = nazwa self.nazwa = nazwa
self.stan = stan self.stan = stan
self.srodek = srodek self.srodek = srodek
"""
def __init__(self, nazwa):
self.nazwa = nazwa
self.stan = Stan.Stan()
if nazwa == "dirt":
self.stan.koszt = 0
self.stan.nawodnienie = 100
elif nazwa == "mud":
self.stan.koszt = 15
self.stan.nawodnienie = 100
else:
self.stan.set_random()
if nazwa == "pszenica":
self.stan.koszt = 7
elif nazwa == "kukurydza":
self.stan.koszt = 9
elif nazwa == "ziemniak":
self.stan.koszt = 2
elif nazwa == "slonecznik":
self.stan.koszt = 5
elif nazwa == "borowka":
self.stan.koszt = 3
else: # winogrono
self.stan.koszt = 4
self.srodek = None
def __init__(self,nazwa):
self.nazwa=nazwa
self.stan=Stan.Stan()
self.stan.set_random()
self.srodek=None
def checkSrodek(self): def checkSrodek(self):
#może wykorzystać AI do porównywania zdjęć #może wykorzystać AI do porównywania zdjęć

View File

@ -45,6 +45,10 @@ 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_stone_image(self):
self.plant_image=self.image_loader.return_stone()
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()
@ -57,6 +61,7 @@ class Slot:
def print_status(self): def print_status(self):
return f"wspolrzedne: (X:{self.x_axis} Y:{self.y_axis}) "+self.plant.report_status() return f"wspolrzedne: (X:{self.x_axis} Y:{self.y_axis}) "+self.plant.report_status()
def irrigatePlant(self): def irrigatePlant(self):
self.plant.stan.nawodnienie = 100 self.plant.stan.nawodnienie = 100

View File

@ -7,6 +7,7 @@ class Stan:
wzrost = None #[int] 0-100 (75-100: scinanie), wzrasta w zaleznosci od rosliny: aktualizowane bedzie "w tle" wzrost = None #[int] 0-100 (75-100: scinanie), wzrasta w zaleznosci od rosliny: aktualizowane bedzie "w tle"
choroba = None #[string] brak, grzyb, bakteria, pasożyt choroba = None #[string] brak, grzyb, bakteria, pasożyt
akcja = None #[Akcja] akcja = None #[Akcja]
koszt = None #[int] 0-15, im więcej tym trudniej wjechać
@ -48,4 +49,4 @@ class Stan:
return self.nawodnienie return self.nawodnienie
def report_all(self): def report_all(self):
return f"Nawodnienie: {self.nawodnienie} Zyznosc: {self.zyznosc} Wzrost: {self.wzrost} Choroba: {self.choroba}" return f"Nawodnienie: {self.nawodnienie} Zyznosc: {self.zyznosc} Wzrost: {self.wzrost} Choroba: {self.choroba} Koszt wejścia: {self.koszt}"

View File

@ -1,6 +1,8 @@
import time import time
import pygame import pygame
import random import random
import Pole
import displayControler as dCon import displayControler as dCon
import Slot import Slot
import Osprzet import Osprzet
@ -137,13 +139,14 @@ class Tractor:
def snake_move(self,pole,x,y): def snake_move(self,pole,x,y):
next_slot_coordinates=(x,y) next_slot_coordinates=(x,y)
if(self.do_move_if_valid(pole,next_slot_coordinates)): if(self.do_move_if_valid(pole,next_slot_coordinates)):
if x == 0 and y == 0: if (x,y) not in Pole.stoneList:
hydrateIndex = -1 if x == 0 and y == 0:
elif pole.get_slot_from_cord((x,y)).get_hydrate_stats() < 60: hydrateIndex = -1
hydrateIndex = 0 elif pole.get_slot_from_cord((x,y)).get_hydrate_stats() < 60:
else: hydrateIndex = 0
hydrateIndex = 1 else:
self.slot_hydrate_dict[(x,y)]= hydrateIndex #Budowanie slownika slotow z poziomem nawodnienia dla traktorka hydrateIndex = 1
self.slot_hydrate_dict[(x,y)]= hydrateIndex #Budowanie slownika slotow z poziomem nawodnienia dla traktorka
self.clock.tick(10) self.clock.tick(10)
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.QUIT:

View File

@ -1,6 +1,6 @@
CUBE_SIZE = 64 CUBE_SIZE = 64
NUM_X = 6 NUM_X = 20
NUM_Y = 3 NUM_Y = 12
#returns true if tractor can move to specified slot #returns true if tractor can move to specified slot
def isValidMove(x, y): def isValidMove(x, y):

BIN
images/dirt.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

BIN
images/mud.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

BIN
images/stone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB