This commit is contained in:
Tomasz Adamczyk 2021-04-24 20:43:09 +02:00
parent 56bebed942
commit 9e4c21f600
8 changed files with 76 additions and 57 deletions

View File

@ -3,6 +3,8 @@
<component name="ChangeListManager">
<list default="true" id="56453584-72bd-49f4-a39c-fccf91ab20c6" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/astar.py" beforeDir="false" afterPath="$PROJECT_DIR$/astar.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/definitions.py" beforeDir="false" afterPath="$PROJECT_DIR$/definitions.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/map.py" beforeDir="false" afterPath="$PROJECT_DIR$/map.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/py.py" beforeDir="false" afterPath="$PROJECT_DIR$/py.py" afterDir="false" />
</list>
@ -119,6 +121,8 @@
<workItem from="1618219455026" duration="134000" />
<workItem from="1619199327277" duration="68000" />
<workItem from="1619200872847" duration="13871000" />
<workItem from="1619260796098" duration="514000" />
<workItem from="1619278079464" duration="10402000" />
</task>
<servers />
</component>
@ -130,42 +134,42 @@
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="690" y="287" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/0.0.1920.1080@0.0.1920.1080" timestamp="1617994393023" />
<state width="1879" height="364" key="GridCell.Tab.0.bottom" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.0.bottom" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.0.bottom/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.0.center" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.0.bottom/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.0.center" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.0.center/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.0.left" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.0.center/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.0.left" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.0.left/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.0.right" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.0.left/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.0.right" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.0.right/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.1.bottom" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.0.right/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.1.bottom" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.1.bottom/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.1.center" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.1.bottom/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.1.center" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.1.center/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.1.left" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.1.center/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.1.left" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.1.left/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state width="1879" height="364" key="GridCell.Tab.1.right" timestamp="1619215367013">
<state width="1879" height="364" key="GridCell.Tab.1.left/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state width="1879" height="364" key="GridCell.Tab.1.right" timestamp="1619289752045">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1879" height="364" key="GridCell.Tab.1.right/0.0.1920.1080@0.0.1920.1080" timestamp="1619215367013" />
<state x="0" y="0" key="com.intellij.ide.util.TipDialog" timestamp="1618219454594">
<state width="1879" height="364" key="GridCell.Tab.1.right/0.0.1920.1080@0.0.1920.1080" timestamp="1619289752045" />
<state x="0" y="0" key="com.intellij.ide.util.TipDialog" timestamp="1619278080559">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="0" y="0" key="com.intellij.ide.util.TipDialog/0.0.1920.1080@0.0.1920.1080" timestamp="1618219454594" />
<state x="0" y="0" key="com.intellij.ide.util.TipDialog/0.0.1920.1080@0.0.1920.1080" timestamp="1619278080559" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
@ -179,6 +183,6 @@
</breakpoint-manager>
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/SmartTractor$py.coverage" NAME="py Coverage Results" MODIFIED="1619214699579" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/SmartTractor$py.coverage" NAME="py Coverage Results" MODIFIED="1619289620713" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
</project>

Binary file not shown.

Binary file not shown.

View File

@ -46,13 +46,15 @@ class Node: #wierzchołek grafu
def set_y(self, y):
self.y = y
def cost(map, node): #funkcja kosztu : ile kosztuje przejechanie przez dane pole
return map.get_field_cost(int(node.get_x()), int(node.get_y()))
cost = 0
while(node.get_parent() != None):
cost = cost + map.get_field_cost(int(node.get_x()), int(node.get_y())) + 1
node = node.get_parent()
return cost
def heuristic(node, goaltest): #funkcja heurestyki : oszacowuje koszt osiągnięcia stanu końcowego (droga)
return abs(node.get_x() - goaltest[0]) + abs(node.get_y() - goaltest[1])
def f(map, node, goaltest): #funkcja zwracająca sumę funkcji kosztu oraz heurestyki
return cost(map, node) + heuristic(node, goaltest)
# def optimal_goal_test():
def goal_test(elem, goaltest): #funkcja sprawdzająca czy położenie traktora równa się położeniu punktu docelowego, jeśli tak zwraca prawdę, w przeciwnym wypadku fałsz
if elem.get_x() == goaltest[0] and elem.get_y() == goaltest[1]:
return True
@ -60,9 +62,9 @@ def goal_test(elem, goaltest): #funkcja sprawdzająca czy położenie traktora r
return False
def print_moves(elem): #zwraca listę ruchów jakie należy wykonać by dotrzeć do punktu docelowego
moves_list = []
while (elem[0].get_parent() != None):
moves_list.append(elem[0].get_action())
elem = elem[0].get_parent()
while (elem.get_parent() != None):
moves_list.append(elem.get_action())
elem = elem.get_parent()
moves_list.reverse()
return moves_list
def succ(elem): #funkcja następnika, przypisuje jakie akcje są możliwe do wykonania na danym polu oraz jaki będzie stan (kierunek, położenie) po wykonaniu tej akcji
@ -101,18 +103,18 @@ def graphsearch(fringe, explored, istate, succ, goaltest, f, map): #przeszukiwan
elem = fringe.pop(0) #zdejmujemy wierzchołek z kolejki fringe i rozpatrujemy go
temp = copy.copy(elem[0])
if goal_test(elem[0], goaltest) is True: #jeżeli osiągniemy cel w trakcie przeszukiwania grafu wszerz (wjedziemy na pole docelowe) : zwracamy listę ruchów, po których wykonaniu dotrzemy na miejsce
return print_moves(elem)
return print_moves(elem[0])
explored.append(elem) #dodajemy wierzchołek do listy wierzchołków odwiedzonych
for (action, state) in succ(temp): #iterujemy po wszystkich możliwych akcjach i stanach otrzymanych dla danego wierzchołka grafu
fringe_tuple = []
fringe_tuple_prio = []
explored_tuple = []
for (x, y) in fringe:
for (x, y) in fringe:
fringe_tuple.append((x.get_direction(), x.get_x(), x.get_y()))
fringe_tuple_prio.append(((x.get_direction(), x.get_x(), x.get_y()), y))
for (x, y) in explored:
explored_tuple.append((x.get_direction(), x.get_x(), x.get_y()))
x = Node(action, state[0], elem, state[1], state[2]) #stworzenie nowego wierzchołka, którego rodzicem jest elem
x = Node(action, state[0], elem[0], state[1], state[2]) #stworzenie nowego wierzchołka, którego rodzicem jest elem
p = f(map, x, goaltest) #liczy priorytet
if state not in fringe_tuple and state not in explored_tuple: #jeżeli stan nie znajduje się na fringe oraz nie znajduje się w liście wierzchołków odwiedzonych
fringe.append((x, p)) #dodanie wierzchołka na fringe
@ -123,6 +125,7 @@ def graphsearch(fringe, explored, istate, succ, goaltest, f, map): #przeszukiwan
if str(state_prio) == str(state):
if r > p:
fringe.insert(i, (x, p)) #zamiana state, który należy do fringe z priorytetem r na state z priorytetem p (niższym)
fringe.pop(i + 1)
fringe = sorted(fringe, key=itemgetter(1)) #sortowanie fringe'a według priorytetu
break
i = i + 1

View File

@ -2,6 +2,8 @@
import os
import pygame
BLOCK_SIZE = 60
BEETROOTS_ADULT_COST = 4
BEETROOTS_GROW_COST = 10
BEETROOTS_GROW_TIME = 5
BEETROOTS_MAXIMUM_STATE = BEETROOTS_GROW_TIME * 3 + 1
BEETROOTS_STAGE_0 = pygame.image.load(os.path.join('resources', 'beetroots_stage_0.png'))
@ -12,6 +14,8 @@ BEETROOTS_STAGE_2 = pygame.image.load(os.path.join('resources', 'beetroots_stage
BEETROOTS_STAGE_2 = pygame.transform.scale(BEETROOTS_STAGE_2, (BLOCK_SIZE, BLOCK_SIZE))
BEETROOTS_STAGE_3 = pygame.image.load(os.path.join('resources', 'beetroots_stage_3.png'))
BEETROOTS_STAGE_3 = pygame.transform.scale(BEETROOTS_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE))
CARROTS_ADULT_COST = 4
CARROTS_GROW_COST = 10
CARROTS_GROW_TIME = 5
CARROTS_MAXIMUM_STATE = CARROTS_GROW_TIME * 3 + 1
CARROTS_STAGE_0 = pygame.image.load(os.path.join('resources', 'carrots_stage_0.png'))
@ -24,13 +28,18 @@ CARROTS_STAGE_3 = pygame.image.load(os.path.join('resources', 'carrots_stage_3.p
CARROTS_STAGE_3 = pygame.transform.scale(CARROTS_STAGE_3, (BLOCK_SIZE, BLOCK_SIZE))
DIRT = pygame.image.load(os.path.join('resources', 'dirt.png'))
DIRT = pygame.transform.scale(DIRT, (BLOCK_SIZE, BLOCK_SIZE))
DIRT_COST = 2
HEIGHT_AMOUNT, WIDTH_AMOUNT = 10, 10
HEIGHT, WIDTH = BLOCK_SIZE * HEIGHT_AMOUNT, BLOCK_SIZE * WIDTH_AMOUNT
FARMLAND_DRY = pygame.image.load(os.path.join('resources', 'farmland_dry.png'))
FARMLAND_DRY = pygame.transform.scale(FARMLAND_DRY, (BLOCK_SIZE, BLOCK_SIZE))
FARMLAND_DRY_COST = 3
FARMLAND_WET = pygame.image.load(os.path.join('resources', 'farmland_wet.png'))
FARMLAND_WET = pygame.transform.scale(FARMLAND_WET, (BLOCK_SIZE, BLOCK_SIZE))
FPS = 1
FARMLAND_WET_COST = 1
FPS = 10
POTATOES_ADULT_COST = 4
POTATOES_GROW_COST = 10
POTATOES_GROW_TIME = 5
POTATOES_MAXIMUM_STATE = POTATOES_GROW_TIME * 3 + 1
POTATOES_STAGE_0 = pygame.image.load(os.path.join('resources', 'potatoes_stage_0.png'))
@ -45,6 +54,7 @@ SPONGE = pygame.image.load(os.path.join('resources', 'sponge.png'))
SPONGE = pygame.transform.scale(SPONGE, (BLOCK_SIZE, BLOCK_SIZE))
STATION = pygame.image.load(os.path.join('resources', 'rail_normal.png'))
STATION = pygame.transform.scale(STATION, (BLOCK_SIZE, BLOCK_SIZE))
STATION_COST = 5
TRACTOR_DIRECTION_EAST_TEXTURE = pygame.image.load(os.path.join('resources', 'minecart_command_block_east.png'))
TRACTOR_DIRECTION_EAST_TEXTURE = pygame.transform.scale(TRACTOR_DIRECTION_EAST_TEXTURE, (BLOCK_SIZE, BLOCK_SIZE))
TRACTOR_DIRECTION_NORTH_TEXTURE = pygame.image.load(os.path.join('resources', 'minecart_command_block_north.png'))
@ -58,10 +68,12 @@ TRACTOR_DIRECTION_NORTH = 1
TRACTOR_DIRECTION_SOUTH = 3
TRACTOR_DIRECTION_WEST = 4
TRACTOR_FERTILIZER = 2
TRACTOR_FUEL = 200
TRACTOR_FUEL = 99999999999999
TRACTOR_AMOUNT_OF_SEEDS_EACH_TYPE = 20
TRACTOR_MAXIMUM_COLLECTED_PLANTS = 80
TRACTOR_WATER_LEVEL = 40
WHEAT_ADULT_COST = 4
WHEAT_GROW_COST = 10
WHEAT_GROW_TIME = 5
WHEAT_MAXIMUM_STATE = WHEAT_GROW_TIME * 7 + 1
WHEAT_STAGE_0 = pygame.image.load(os.path.join('resources', 'wheat_stage_0.png'))

52
map.py
View File

@ -23,32 +23,6 @@ class Map:
temp_field = field.Field(temp_plant, temp_rect, temp_soil)
temp_map_field.append(temp_field)
self.fields.append(temp_map_field)
def get_field_cost(self, x, y): #zwraca koszt danego pola
field = self.fields[x][y]
if field.get_plant().get_name() == "station" and field.get_plant().get_state() == -1:
return 5
elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.BEETROOTS_GROW_TIME:
return 10
elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE:
return 4
elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.CARROTS_GROW_TIME:
return 10
elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE:
return 4
elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.POTATOES_GROW_TIME:
return 10
elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE:
return 4
elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 7 * definitions.WHEAT_GROW_TIME:
return 10
elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE:
return 4
elif field.get_soil().get_state() is False:
return 2
elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is False:
return 3
elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is True:
return 1
def fill_map(self): #wypełnia mapę teksturami na podstawie logicznego stanu pól
for i in range(definitions.WIDTH_AMOUNT):
for j in range(definitions.HEIGHT_AMOUNT):
@ -107,6 +81,32 @@ class Map:
elif block != definitions.DIRT or block != definitions.FARMLAND_DRY or block != definitions.FARMLAND_WET:
definitions.WINDOW.blit(definitions.FARMLAND_WET, (rect.x, rect.y))
definitions.WINDOW.blit(block, (rect.x, rect.y))
def get_field_cost(self, x, y): #zwraca koszt danego pola
field = self.fields[x][y]
if field.get_plant().get_name() == "station" and field.get_plant().get_state() == -1:
return definitions.STATION_COST
elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.BEETROOTS_GROW_TIME:
return definitions.BEETROOTS_GROW_COST
elif field.get_plant().get_name() == "beetroot" and field.get_plant().get_state() == definitions.BEETROOTS_MAXIMUM_STATE:
return definitions.BEETROOTS_ADULT_COST
elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.CARROTS_GROW_TIME:
return definitions.CARROTS_GROW_COST
elif field.get_plant().get_name() == "carrot" and field.get_plant().get_state() == definitions.CARROTS_MAXIMUM_STATE:
return definitions.CARROTS_ADULT_COST
elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 3 * definitions.POTATOES_GROW_TIME:
return definitions.POTATOES_GROW_COST
elif field.get_plant().get_name() == "potato" and field.get_plant().get_state() == definitions.POTATOES_MAXIMUM_STATE:
return definitions.POTATOES_ADULT_COST
elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() > 0 and field.get_plant().get_state() <= 7 * definitions.WHEAT_GROW_TIME:
return definitions.WHEAT_GROW_COST
elif field.get_plant().get_name() == "wheat" and field.get_plant().get_state() == definitions.WHEAT_MAXIMUM_STATE:
return definitions.WHEAT_ADULT_COST
elif field.get_soil().get_state() is False:
return definitions.DIRT_COST
elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is False:
return definitions.FARMLAND_DRY_COST
elif field.get_soil().get_state() is True and field.get_soil().get_water_level() is True:
return definitions.FARMLAND_WET_COST
def draw_window(self, tractor1, tractor1_rect): #rysuje mapę
self.fill_map()
if tractor1.get_direction() == definitions.TRACTOR_DIRECTION_EAST:

2
py.py
View File

@ -29,7 +29,7 @@ def main():
if not move_list and plant.Plant.if_any_mature_plant(map1) is True: #jeżeli są jakieś ruchy do wykonania w move_list oraz istnieje jakaś dojrzała roślina
istate = graph.Istate(tractor1.get_direction(), tractor1.get_x() / definitions.BLOCK_SIZE, tractor1.get_y() / definitions.BLOCK_SIZE) #stan początkowy traktora (jego orientacja oraz jego aktualne współrzędne)
#move_list = (graph.graphsearch([], [], istate, graph.succ, plant.Plant.get_closest_mature_plant(map1, tractor1))) #lista z ruchami, które należy po kolei wykonać, graph
move_list = (astar.graphsearch([], [], istate, graph.succ, plant.Plant.get_closest_mature_plant(map1, tractor1), astar.f, map1)) #lista z ruchami, które należy po kolei wykonać, astar
move_list = (astar.graphsearch([], [], istate, graph.succ, plant.Plant.get_closest_mature_plant(map1, istate), astar.f, map1)) #lista z ruchami, które należy po kolei wykonać, astar
elif move_list: #jeżeli move_list nie jest pusta
tractor1.handle_movement(move_list.pop(0), tractor1_rect) #wykonaj kolejny ruch oraz zdejmij ten ruch z początku listy
else: