Compare commits
No commits in common. "master" and "algorytm_bfs" have entirely different histories.
master
...
algorytm_b
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,5 +1,2 @@
|
||||
__pycache__/
|
||||
.idea/
|
||||
tree.png
|
||||
dataset/
|
||||
dataset.zip
|
||||
.idea/
|
284
AStar.py
284
AStar.py
@ -1,284 +0,0 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
import random
|
||||
import pygame
|
||||
import Node
|
||||
import BFS
|
||||
from displayControler import NUM_X, NUM_Y
|
||||
from Pole import stoneList
|
||||
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):
|
||||
# Oblicz odległość Manhattanowską między aktualnym stanem a celem
|
||||
manhattan_distance = abs(state['x'] - goal[0]) + abs(state['y'] - goal[1])
|
||||
return manhattan_distance
|
||||
|
||||
|
||||
'''def get_cost_for_plant(plant_name):
|
||||
plant_costs = {
|
||||
"pszenica": 7,
|
||||
"kukurydza": 9,
|
||||
"ziemniak": 2,
|
||||
"slonecznik": 5,
|
||||
"borowka": 3,
|
||||
"winogrono": 4,
|
||||
"mud": 15,
|
||||
"dirt": 0,
|
||||
}
|
||||
if plant_name in plant_costs:
|
||||
return plant_costs[plant_name]
|
||||
else:
|
||||
# Jeśli nazwa rośliny nie istnieje w słowniku, zwróć domyślną wartość
|
||||
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
|
||||
|
||||
fringe = PriorityQueue() # Kolejka priorytetowa dla wierzchołków do rozpatrzenia
|
||||
explored = [] # Lista odwiedzonych stanów
|
||||
obrot = 1
|
||||
|
||||
# Tworzenie węzła początkowego
|
||||
x = Node.Node(istate)
|
||||
x.g = 0
|
||||
x.h = heuristic(x.state, goalTreasure)
|
||||
fringe.put((x.g + x.h, x)) # Dodanie węzła do kolejki
|
||||
total_cost = 0
|
||||
|
||||
while not fringe.empty():
|
||||
_, elem = fringe.get() # Pobranie węzła z najniższym priorytetem
|
||||
|
||||
if BFS.goalTest3(elem.state, goalTreasure): # Sprawdzenie, czy osiągnięto cel
|
||||
path = []
|
||||
cost_list=[]
|
||||
while elem.parent is not None: # Odtworzenie ścieżki
|
||||
path.append([elem.parent, elem.action])
|
||||
elem = elem.parent
|
||||
for node, action in 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)
|
||||
|
||||
for resp in succ3A(elem.state):
|
||||
child_state = resp[1]
|
||||
if child_state not in explored:
|
||||
child = Node.Node(child_state)
|
||||
child.parent = elem
|
||||
child.action = resp[0]
|
||||
|
||||
# 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)
|
||||
# Pobranie kosztu dla danej rośliny
|
||||
#plant_cost = get_cost_for_plant(plant_name)
|
||||
|
||||
if child.action == "left" or child.action == "right":
|
||||
child.g = elem.g + obrot
|
||||
else:
|
||||
child.g = elem.g + plant_cost
|
||||
|
||||
# Obliczenie heurystyki dla dziecka
|
||||
child.h = heuristic(child.state, goalTreasure)
|
||||
|
||||
in_fringe = False
|
||||
for priority, item in fringe.queue:
|
||||
if item.state == child.state:
|
||||
in_fringe = True
|
||||
if priority > child.g + child.h:
|
||||
# Jeśli znaleziono węzeł w kolejce o gorszym priorytecie, zastąp go nowym
|
||||
fringe.queue.remove((priority, item))
|
||||
fringe.put((child.g + child.h, child))
|
||||
break
|
||||
|
||||
if not in_fringe:
|
||||
# Jeśli stan dziecka nie jest w kolejce, dodaj go do kolejki
|
||||
fringe.put((child.g + child.h, child))
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
quit()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_plant_name_and_cost_from_coordinates(x, y, pole):
|
||||
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
|
||||
if slot.plant: # Sprawdzenie, czy na slocie znajduje się roślina
|
||||
return slot.plant.stan.koszt # Zwrócenie nazwy rośliny na slocie
|
||||
else:
|
||||
return 0 # jeśli na slocie nie ma rośliny
|
||||
else:
|
||||
return 0 # 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,
|
||||
#tylko musiałam dodac sprawdzenie kolizji, bo traktor brał sloty z Y których nie ma na planszy
|
||||
def succ3A(state):
|
||||
resp = []
|
||||
if state["direction"] == "N":
|
||||
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(["right", {'x': state["x"], 'y': state["y"], 'direction': "E"}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "W"}])
|
||||
elif state["direction"] == "S":
|
||||
if state["y"] < NUM_Y - 1 and (state['x'], state["y"] + 1) not in stoneList:
|
||||
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(["left", {'x': state["x"], 'y': state["y"], 'direction': "E"}])
|
||||
elif state["direction"] == "E":
|
||||
if state["x"] < NUM_X - 1 and (state['x'] + 1, state["y"]) not in stoneList:
|
||||
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(["left", {'x': state["x"], 'y': state["y"], 'direction': "N"}])
|
||||
else: #state["direction"] == "W"
|
||||
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(["right", {'x': state["x"], 'y': state["y"], 'direction': "N"}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "S"}])
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
|
||||
|
||||
def heuristic2(state, goal):
|
||||
# Oblicz odległość Manhattanowską między aktualnym stanem a celem
|
||||
manhattan_distance = (abs(state['x'] - goal[0]) + abs(state['y'] - goal[1])) * 2.5
|
||||
return manhattan_distance
|
||||
|
||||
|
||||
def A_star2(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
|
||||
fringe = PriorityQueue() # Kolejka priorytetowa dla wierzchołków do rozpatrzenia
|
||||
explored = [] # Lista odwiedzonych stanów
|
||||
obrot = 1
|
||||
|
||||
# Tworzenie węzła początkowego
|
||||
x = Node.Node(istate)
|
||||
x.g = 0
|
||||
x.h = heuristic2(x.state, goalTreasure)
|
||||
fringe.put((x.g + x.h, x)) # Dodanie węzła do kolejki
|
||||
total_cost=0
|
||||
|
||||
while not fringe.empty():
|
||||
_, elem = fringe.get() # Pobranie węzła z najniższym priorytetem
|
||||
|
||||
if BFS.goalTest3(elem.state, goalTreasure): # Sprawdzenie, czy osiągnięto cel
|
||||
path = []
|
||||
cost_list=[]
|
||||
while elem.parent is not None: # Odtworzenie ścieżki
|
||||
path.append([elem.parent, elem.action])
|
||||
elem = elem.parent
|
||||
for node, action in 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)
|
||||
|
||||
for resp in succ3A(elem.state):
|
||||
child_state = resp[1]
|
||||
if child_state not in explored:
|
||||
child = Node.Node(child_state)
|
||||
child.parent = elem
|
||||
child.action = resp[0]
|
||||
|
||||
# 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)
|
||||
|
||||
if child.action == "left" or child.action == "right":
|
||||
child.g = elem.g + obrot
|
||||
else:
|
||||
child.g = elem.g + plant_cost
|
||||
# Obliczenie heurystyki dla dziecka
|
||||
child.h = heuristic2(child.state, goalTreasure)
|
||||
|
||||
in_fringe = False
|
||||
for priority, item in fringe.queue:
|
||||
if item.state == child.state:
|
||||
in_fringe = True
|
||||
if priority > child.g + child.h:
|
||||
# Jeśli znaleziono węzeł w kolejce o gorszym priorytecie, zastąp go nowym
|
||||
fringe.queue.remove((priority, item))
|
||||
fringe.put((child.g + child.h, child))
|
||||
break
|
||||
|
||||
if not in_fringe:
|
||||
# Jeśli stan dziecka nie jest w kolejce, dodaj go do kolejki
|
||||
fringe.put((child.g + child.h, child))
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
quit()
|
||||
|
||||
return False
|
||||
|
||||
"""
|
||||
TO TEST SPEED OF ASTAR
|
||||
|
||||
test_speed = False
|
||||
|
||||
if test_speed:
|
||||
time1 = 0
|
||||
time2 = 0
|
||||
cost1 = 0
|
||||
cost2 = 0
|
||||
for i in range(500):
|
||||
print(i)
|
||||
start = time.time()
|
||||
aStarRoot, cost_list, total_cost = AStar.A_star({'x': 0, 'y': 0, 'direction': "E"}, pole, goalTreasure)
|
||||
end = time.time()
|
||||
time1 += end - start
|
||||
cost1 += total_cost
|
||||
start = time.time()
|
||||
aStarRoot2, cost_list, total_cost = AStar.A_star2({'x': 0, 'y': 0, 'direction': "E"}, pole, goalTreasure)
|
||||
end = time.time()
|
||||
time2 += end - start
|
||||
cost2 += total_cost
|
||||
print(time1, time2)
|
||||
print(float(cost1 / 1000), float(cost2 / 1000))
|
||||
"""
|
267
BFS.py
267
BFS.py
@ -1,267 +0,0 @@
|
||||
import random
|
||||
|
||||
import pygame
|
||||
import Node
|
||||
from displayControler import NUM_X, NUM_Y
|
||||
from Pole import stoneList
|
||||
|
||||
|
||||
def goalTest1(hIndex):
|
||||
for i in list(hIndex.values()):
|
||||
if i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def succ1(state):
|
||||
resp = []
|
||||
hIndex = state["hydradeIndex"].copy()
|
||||
if state["direction"] == "N":
|
||||
if state["y"] > 0:
|
||||
if hIndex[state["x"], state["y"]-1] == 0:
|
||||
hIndex[state["x"], state["y"] - 1] = 1
|
||||
resp.append(["forward", {'x': state["x"], 'y': state["y"]-1, 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "E", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "W", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
elif state["direction"] == "S":
|
||||
if state["y"] < NUM_Y-1:
|
||||
if hIndex[state["x"], state["y"]+1] == 0:
|
||||
hIndex[state["x"], state["y"] + 1] = 1
|
||||
resp.append(["forward", {'x': state["x"], 'y': state["y"]+1, 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "W", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "E", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
elif state["direction"] == "E":
|
||||
if state["x"] < NUM_X-1:
|
||||
if hIndex[state["x"]+1, state["y"]] == 0:
|
||||
hIndex[state["x"] + 1, state["y"]] = 1
|
||||
resp.append(["forward", {'x': state["x"]+1, 'y': state["y"], 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "S", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "N", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
else: #state["zwrot"] == "W"
|
||||
if state["x"] > 0:
|
||||
if hIndex[state["x"]-1, state["y"]] == 0:
|
||||
hIndex[state["x"] - 1, state["y"]] = 1
|
||||
resp.append(["forward", {'x': state["x"]-1, 'y': state["y"], 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "N", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "S", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def check1(tab, state):
|
||||
for i in tab:
|
||||
if i.state == state:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def BFS1(istate):
|
||||
|
||||
|
||||
fringe = []
|
||||
explored = []
|
||||
|
||||
x = Node.Node(istate)
|
||||
fringe.append(x)
|
||||
|
||||
while True:
|
||||
|
||||
|
||||
if fringe == []:
|
||||
return False
|
||||
|
||||
elem = fringe.pop(0)
|
||||
|
||||
if goalTest1(elem.state["hydradeIndex"]):
|
||||
x = elem
|
||||
tab = []
|
||||
while x.parent != None:
|
||||
tab.append([x.parent, x.action])
|
||||
x = x.parent
|
||||
return tab
|
||||
explored.append(elem)
|
||||
|
||||
for resp in succ1(elem.state):
|
||||
if check1(fringe, resp[1]) and check1(explored, resp[1]):
|
||||
x = Node.Node(resp[1])
|
||||
x.parent = elem
|
||||
x.action = resp[0]
|
||||
fringe.append(x)
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
quit()
|
||||
|
||||
|
||||
|
||||
|
||||
def goalTest3(state, goalTreassure):
|
||||
if state["x"] == goalTreassure[0] and state["y"] == goalTreassure[1]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def succ3(state):
|
||||
resp = []
|
||||
if state["direction"] == "N":
|
||||
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(["right", {'x': state["x"], 'y': state["y"], 'direction': "E"}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "W"}])
|
||||
elif state["direction"] == "S":
|
||||
if state["y"] < NUM_Y - 1 and (state['x'], state["y"] + 1) not in stoneList:
|
||||
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(["left", {'x': state["x"], 'y': state["y"], 'direction': "E"}])
|
||||
elif state["direction"] == "E":
|
||||
if state["x"] < NUM_X - 1 and (state['x'] + 1, state["y"]) not in stoneList:
|
||||
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(["left", {'x': state["x"], 'y': state["y"], 'direction': "N"}])
|
||||
else: #state["zwrot"] == "W"
|
||||
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(["right", {'x': state["x"], 'y': state["y"], 'direction': "N"}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "S"}])
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def check3(tab, state):
|
||||
for i in tab:
|
||||
if i.state == state:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def BFS3(istate,GT):
|
||||
randomGT=False
|
||||
if(randomGT==True):
|
||||
goalTreassuere = (random.randint(0,NUM_X-1), random.randint(0,NUM_Y-1))
|
||||
else:
|
||||
goalTreassuere=GT
|
||||
print(goalTreassuere)
|
||||
fringe = []
|
||||
explored = []
|
||||
|
||||
x = Node.Node(istate)
|
||||
fringe.append(x)
|
||||
|
||||
while True:
|
||||
|
||||
if fringe == []:
|
||||
return False
|
||||
|
||||
elem = fringe.pop(0)
|
||||
|
||||
if goalTest3(elem.state, goalTreassuere):
|
||||
x = elem
|
||||
tab = []
|
||||
while x.parent != None:
|
||||
tab.append([x.parent, x.action])
|
||||
x = x.parent
|
||||
return tab
|
||||
|
||||
explored.append(elem)
|
||||
|
||||
for resp in succ3(elem.state):
|
||||
if check3(fringe, resp[1]) and check3(explored, resp[1]):
|
||||
x = Node.Node(resp[1])
|
||||
x.parent = elem
|
||||
x.action = resp[0]
|
||||
fringe.append(x)
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
quit()
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
def goalTest(hIndex):
|
||||
for i in list(hIndex.values()):
|
||||
if i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def succ(state):
|
||||
resp = []
|
||||
hIndex = state["hydradeIndex"].copy()
|
||||
|
||||
if state["direction"] == "N":
|
||||
if state["y"] > 0:
|
||||
if hIndex[state["x"], state["y"]-1] == 0:
|
||||
hIndex[state["x"], state["y"] - 1] = 1
|
||||
resp.append(["forward", {'x': state["x"], 'y': state["y"]-1, 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "E", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "W", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
elif state["direction"] == "S":
|
||||
if state["y"] < dCon.NUM_Y-1:
|
||||
if hIndex[state["x"], state["y"]+1] == 0:
|
||||
hIndex[state["x"], state["y"] + 1] = 1
|
||||
resp.append(["forward", {'x': state["x"], 'y': state["y"]+1, 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "W", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "E", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
elif state["direction"] == "E":
|
||||
if state["x"] < dCon.NUM_X-1:
|
||||
if hIndex[state["x"]+1, state["y"]] == 0:
|
||||
hIndex[state["x"] + 1, state["y"]] = 1
|
||||
resp.append(["forward", {'x': state["x"]+1, 'y': state["y"], 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "S", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "N", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
else: #state["direction"] == "W"
|
||||
if state["x"] > 0:
|
||||
if hIndex[state["x"]-1, state["y"]] == 0:
|
||||
hIndex[state["x"] - 1, state["y"]] = 1
|
||||
resp.append(["forward", {'x': state["x"]-1, 'y': state["y"], 'direction': state["direction"], 'hydradeIndex': hIndex}])
|
||||
resp.append(["right", {'x': state["x"], 'y': state["y"], 'direction': "N", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
resp.append(["left", {'x': state["x"], 'y': state["y"], 'direction': "S", 'hydradeIndex': state["hydradeIndex"].copy()}])
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def check(tab, state):
|
||||
for i in tab:
|
||||
if i.state == state:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def BFS(istate):
|
||||
fringe = []
|
||||
explored = []
|
||||
|
||||
x = Node.Node(istate)
|
||||
fringe.append(x)
|
||||
|
||||
while True:
|
||||
if fringe == []:
|
||||
return False
|
||||
|
||||
elem = fringe.pop(0)
|
||||
|
||||
if goalTest(elem.state["hydradeIndex"]):
|
||||
x = elem
|
||||
tab = []
|
||||
while x.parent != None:
|
||||
tab.append(x.action)
|
||||
x = x.parent
|
||||
return tab
|
||||
|
||||
explored.append(elem)
|
||||
|
||||
for resp in succ(elem.state):
|
||||
if check(fringe, resp[1]) and check(explored, resp[1]):
|
||||
x = Node.Node(resp[1])
|
||||
x.parent = elem
|
||||
x.action = resp[0]
|
||||
fringe.append(x)
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
49
Climate.py
49
Climate.py
@ -1,49 +0,0 @@
|
||||
#THESE DICTIONARIES ARE USED FOR DISPLAY AND FOR DOCUMENTATION PURPOSES
|
||||
|
||||
seasons={
|
||||
0:"zima",
|
||||
1:"wiosna",
|
||||
2:"lato",
|
||||
3:"jesien"}
|
||||
|
||||
time={
|
||||
0:"rano",
|
||||
1:"poludnie",
|
||||
2:"wieczor",
|
||||
3:"noc"}
|
||||
|
||||
rain={
|
||||
0:"brak",
|
||||
1:"lekki deszcz",
|
||||
2:"normalny deszcz",
|
||||
3:"ulewa"
|
||||
}
|
||||
|
||||
temperature={
|
||||
0:"bardzo zimno",
|
||||
1:"zimno",
|
||||
2:"przecietnie",
|
||||
3:"cieplo",
|
||||
4:"upal",}
|
||||
|
||||
def getNextSeason(season):
|
||||
if(season==3):
|
||||
return 0
|
||||
else:
|
||||
return season+1
|
||||
|
||||
def getNextTime(currentTime):
|
||||
if(currentTime==3):
|
||||
return 0
|
||||
else:
|
||||
return currentTime+1
|
||||
|
||||
def getAmount(type):
|
||||
if(type=="seasons"):
|
||||
return len(seasons)
|
||||
if(type=="rain"):
|
||||
return len(rain)
|
||||
if(type=="time"):
|
||||
return len(time)
|
||||
if(type=="temperature"):
|
||||
return len(temperature)
|
47
Condition.py
47
Condition.py
@ -1,47 +0,0 @@
|
||||
import random
|
||||
import Climate
|
||||
import Ui
|
||||
|
||||
class Condition:
|
||||
def __init__(self):
|
||||
self.season=self.setRandomSeason()
|
||||
self.currentTime=self.setRandomTime()
|
||||
self.rain=self.setRandomRain()
|
||||
self.temperature=self.setRandomRain()
|
||||
self.clock=0
|
||||
|
||||
def setRandomSeason(self):
|
||||
return self.randomizer(Climate.getAmount("seasons"))
|
||||
|
||||
def setRandomTime(self):
|
||||
return self.randomizer(Climate.getAmount("time"))
|
||||
|
||||
def setRandomRain(self):
|
||||
return self.randomizer(Climate.getAmount("rain"))
|
||||
|
||||
def setRandomTemperature(self):
|
||||
return self.randomizer(Climate.getAmount("temperature"))
|
||||
|
||||
def randomizer(self,max):
|
||||
return random.randint(0,max-1)
|
||||
|
||||
def cycle(self):
|
||||
if(self.clock==11):
|
||||
self.currentTime=0
|
||||
self.rain=self.setRandomRain()
|
||||
self.temperature=self.setRandomTemperature()
|
||||
self.season=Climate.getNextSeason(self.season)
|
||||
self.clock=0
|
||||
return
|
||||
else:
|
||||
self.currentTime=Climate.getNextTime(self.currentTime)
|
||||
self.rain=self.setRandomRain()
|
||||
self.temperature=self.setRandomTemperature()
|
||||
self.clock=self.clock+1
|
||||
|
||||
def return_condition(self):
|
||||
return [self.temperature,self.rain,self.season,self.currentTime]
|
||||
|
||||
|
||||
def getCondition(self):
|
||||
return ([Climate.temperature[self.temperature],Climate.rain[self.rain],Climate.seasons[self.season],Climate.time[self.currentTime]])
|
9219
Data/dataTree.csv
9219
Data/dataTree.csv
File diff suppressed because it is too large
Load Diff
@ -1,248 +0,0 @@
|
||||
plant_water_level,growth,disease,fertility,tractor_water_level,temperature,rain,season,current_time,action
|
||||
1,20,0,40,60,2,0,2,1,1
|
||||
20,40,0,40,60,2,0,2,1,1
|
||||
87,20,0,40,60,2,0,2,1,0
|
||||
27,43,1,40,60,2,0,2,1,0
|
||||
89,56,1,40,60,2,1,1,1,0
|
||||
67,100,1,37,55,1,3,3,3,0
|
||||
67,40,1,87,90,4,0,1,0,0
|
||||
1,20,0,40,60,2,0,0,1,0
|
||||
20,40,0,40,60,2,0,0,1,0
|
||||
87,20,0,56,45,2,0,0,2,0
|
||||
27,43,1,40,60,2,0,0,3,0
|
||||
89,56,1,40,89,2,1,0,1,0
|
||||
67,100,1,37,55,1,3,0,3,0
|
||||
67,40,1,87,90,4,0,0,0,0
|
||||
1,100,0,45,20,2,0,2,1,0
|
||||
20,100,0,40,34,0,1,2,0,0
|
||||
87,100,0,56,60,2,0,1,1,0
|
||||
27,100,0,89,67,1,2,2,2,0
|
||||
89,100,0,40,60,2,1,1,1,0
|
||||
76,100,0,37,55,1,3,3,3,0
|
||||
67,100,0,87,90,4,0,1,0,0
|
||||
1,20,0,40,0,2,0,2,1,0
|
||||
20,40,0,40,0,2,0,2,1,0
|
||||
87,20,0,40,0,2,0,2,1,0
|
||||
27,43,1,40,0,2,0,2,1,0
|
||||
89,56,1,40,0,2,1,1,1,0
|
||||
67,100,1,37,0,1,3,3,3,0
|
||||
67,40,1,87,0,4,0,1,0,0
|
||||
1,20,0,40,0,2,0,0,1,0
|
||||
20,40,0,40,0,2,0,0,1,0
|
||||
87,20,0,56,0,2,0,0,2,0
|
||||
27,43,1,40,0,2,0,0,3,0
|
||||
89,56,1,40,0,2,1,0,1,0
|
||||
67,100,1,37,0,1,3,0,3,0
|
||||
67,40,1,87,0,4,0,0,0,0
|
||||
1,100,0,45,0,2,0,2,1,0
|
||||
20,100,0,40,0,0,1,2,0,0
|
||||
87,100,0,56,0,2,0,1,1,0
|
||||
27,100,0,89,0,1,2,2,2,0
|
||||
89,100,0,40,0,2,1,1,1,0
|
||||
76,100,0,37,0,1,3,3,3,0
|
||||
67,100,0,87,0,4,0,1,0,0
|
||||
1,45,0,56,44,2,1,1,1,1
|
||||
20,55,0,43,34,2,0,2,2,1
|
||||
15,23,0,23,26,2,1,3,3,1
|
||||
45,67,0,12,67,3,0,1,0,1
|
||||
59,88,0,34,87,3,0,2,1,1
|
||||
32,32,0,32,90,3,0,3,2,1
|
||||
44,43,0,19,27,2,0,1,3,1
|
||||
33,11,0,28,76,2,0,2,0,1
|
||||
54,90,0,44,5,3,0,3,1,1
|
||||
21,76,0,50,25,3,1,1,2,1
|
||||
29,64,0,38,36,2,0,2,3,1
|
||||
11,54,0,65,44,3,1,1,2,1
|
||||
23,55,0,34,43,3,0,2,1,1
|
||||
51,32,0,32,62,3,1,3,3,1
|
||||
54,76,0,21,76,2,0,1,2,1
|
||||
95,88,0,43,78,2,0,2,1,0
|
||||
23,23,0,23,9,2,0,3,3,1
|
||||
44,34,0,91,72,3,0,1,0,1
|
||||
33,11,0,82,67,3,0,2,2,1
|
||||
45,9,0,44,50,2,0,3,3,1
|
||||
21,67,0,50,52,2,1,1,0,1
|
||||
92,46,0,83,63,3,0,2,1,0
|
||||
20,55,1,43,34,0,0,2,2,0
|
||||
15,23,1,23,26,0,1,3,3,0
|
||||
45,67,1,12,67,0,0,1,0,0
|
||||
59,88,1,34,87,0,0,2,1,0
|
||||
32,32,0,32,90,0,0,3,2,0
|
||||
44,43,0,19,27,4,0,1,3,0
|
||||
33,11,0,28,76,4,0,2,0,0
|
||||
54,90,0,44,5,4,0,3,1,0
|
||||
21,76,0,50,25,4,1,1,2,0
|
||||
29,64,0,38,36,4,0,2,3,0
|
||||
11,54,0,65,44,0,1,1,2,0
|
||||
23,55,0,34,43,0,0,2,1,0
|
||||
51,32,0,32,62,0,1,3,3,0
|
||||
80,76,1,39,7,3,0,1,0,0
|
||||
98,77,0,15,91,1,3,2,3,0
|
||||
3,48,1,73,41,2,2,0,3,0
|
||||
20,15,1,97,87,4,1,2,1,0
|
||||
93,6,0,37,0,0,1,0,1,0
|
||||
4,31,0,1,5,2,3,1,2,0
|
||||
42,52,0,33,19,3,2,3,0,0
|
||||
76,43,0,77,18,4,0,0,3,0
|
||||
31,13,1,21,42,0,1,2,3,0
|
||||
96,65,1,63,35,1,3,3,2,0
|
||||
29,39,0,40,37,3,3,0,0,0
|
||||
82,53,0,55,9,0,1,3,2,0
|
||||
21,35,0,58,1,1,2,2,0,0
|
||||
92,98,0,69,16,3,0,0,1,0
|
||||
34,23,0,95,2,2,3,0,3,0
|
||||
36,28,0,62,22,0,1,1,1,0
|
||||
66,88,1,10,85,3,1,2,3,0
|
||||
53,51,0,79,90,2,2,3,2,0
|
||||
9,74,0,60,4,4,1,2,3,1
|
||||
17,0,0,38,58,1,2,3,0,0
|
||||
12,76,0,50,25,3,1,1,2,1
|
||||
92,64,0,38,36,2,0,2,3,0
|
||||
11,54,0,65,44,3,1,1,2,1
|
||||
32,55,0,34,43,3,0,2,1,1
|
||||
15,32,0,32,62,3,1,3,3,1
|
||||
45,76,0,21,76,2,0,1,2,1
|
||||
59,88,0,43,78,2,0,2,1,1
|
||||
32,23,0,23,9,2,0,3,3,1
|
||||
14,34,0,91,72,3,0,1,0,1
|
||||
13,11,0,82,67,3,0,2,2,1
|
||||
45,9,0,44,50,2,0,3,3,1
|
||||
21,67,0,50,52,2,1,1,0,1
|
||||
92,46,0,83,63,3,0,2,1,0
|
||||
2,40,1,34,43,1,3,2,2,0
|
||||
51,32,1,32,62,2,1,3,3,0
|
||||
54,76,1,21,76,3,0,1,0,0
|
||||
98,38,0,50,44,4,0,1,0,0
|
||||
63,7,0,93,79,2,0,2,1,1
|
||||
91,59,0,94,24,4,0,3,2,0
|
||||
11,49,0,54,76,2,0,1,3,1
|
||||
33,31,0,59,39,3,0,1,3,1
|
||||
28,50,0,26,0,4,0,2,2,0
|
||||
54,83,0,36,0,3,0,2,1,0
|
||||
49,78,0,68,0,2,0,3,2,0
|
||||
59,21,0,43,100,1,0,3,2,1
|
||||
1,30,0,52,100,2,0,0,3,0
|
||||
60,9,0,40,40,3,0,0,3,0
|
||||
85,94,0,87,85,4,0,1,3,0
|
||||
79,68,0,56,90,1,0,2,2,1
|
||||
75,22,0,25,95,1,0,3,2,1
|
||||
100,51,0,33,12,0,0,2,2,0
|
||||
90,70,0,71,81,0,0,2,1,0
|
||||
47,26,0,6,78,4,0,1,1,1
|
||||
14,89,0,70,18,4,0,1,0,1
|
||||
99,19,0,74,91,2,0,3,0,0
|
||||
18,48,0,15,32,2,0,3,0,1
|
||||
5,57,0,14,34,0,1,1,3,1
|
||||
22,67,0,9,5,0,1,2,2,0
|
||||
95,81,0,46,86,1,1,3,1,0
|
||||
39,65,0,84,0,1,1,0,0,0
|
||||
84,75,0,30,0,2,1,1,1,0
|
||||
86,41,0,2,67,2,1,2,2,0
|
||||
64,53,0,53,47,1,1,3,3,1
|
||||
69,61,0,0,73,2,1,0,0,0
|
||||
94,40,1,0,18,3,1,1,2,0
|
||||
62,82,1,20,50,4,1,2,3,0
|
||||
57,1,1,17,92,0,1,3,2,0
|
||||
80,35,1,58,45,0,0,3,1,0
|
||||
30,47,1,8,47,1,0,2,1,0
|
||||
82,32,0,99,39,1,3,1,3,0
|
||||
20,84,0,0,51,2,3,2,3,0
|
||||
42,88,0,0,54,2,2,2,0,0
|
||||
66,45,0,91,10,3,2,1,0,0
|
||||
81,14,0,19,55,3,0,1,2,1
|
||||
74,37,0,88,78,4,0,3,2,1
|
||||
89,99,0,100,60,4,0,3,3,0
|
||||
15,20,0,45,11,0,0,1,3,1
|
||||
92,28,0,85,90,2,0,1,1,0
|
||||
55,4,0,13,95,2,0,2,1,1
|
||||
2,6,0,35,0,2,0,2,0,0
|
||||
61,56,0,90,0,2,0,3,0,0
|
||||
76,11,0,61,10,3,0,3,1,1
|
||||
26,80,0,57,9,3,0,1,2,1
|
||||
40,44,0,81,8,3,0,2,3,1
|
||||
50,66,0,23,7,3,0,3,0,1
|
||||
48,15,0,77,6,2,0,0,1,0
|
||||
11,54,0,65,44,3,3,1,2,0
|
||||
23,55,0,34,43,3,3,2,1,0
|
||||
51,32,0,32,62,3,3,3,3,0
|
||||
54,76,0,21,76,2,3,1,2,0
|
||||
95,88,0,43,78,2,3,2,1,0
|
||||
23,23,0,23,9,2,3,3,3,0
|
||||
44,34,0,91,72,3,3,1,0,0
|
||||
33,11,0,82,67,3,3,2,2,0
|
||||
45,9,0,44,50,2,3,3,3,0
|
||||
21,67,0,50,52,2,3,1,0,0
|
||||
92,46,0,83,63,3,3,2,1,0
|
||||
20,55,1,43,34,0,3,2,2,0
|
||||
15,23,1,23,26,0,3,3,3,0
|
||||
45,67,1,12,67,0,3,1,0,0
|
||||
59,88,1,34,87,0,3,2,1,0
|
||||
32,32,0,32,90,0,3,3,2,0
|
||||
1,60,0,55,11,0,1,0,0,1
|
||||
2,70,0,44,12,1,1,0,1,1
|
||||
3,44,0,11,13,2,1,0,2,1
|
||||
4,55,0,34,66,3,0,0,3,1
|
||||
5,66,0,90,77,0,0,1,2,1
|
||||
6,22,0,89,88,0,0,2,2,1
|
||||
7,1,0,45,9,0,1,2,3,1
|
||||
8,2,0,34,22,3,1,2,3,1
|
||||
9,3,0,56,34,3,1,0,1,1
|
||||
10,6,0,78,5,3,0,3,1,1
|
||||
11,8,0,36,67,2,0,0,0,1
|
||||
12,59,0,57,23,2,1,1,0,1
|
||||
13,67,0,29,34,1,1,0,1,1
|
||||
14,20,0,30,90,1,1,2,2,1
|
||||
15,21,0,66,89,0,1,3,3,1
|
||||
44,100,0,91,72,3,3,1,0,0
|
||||
33,100,0,82,67,3,3,2,2,0
|
||||
45,100,0,44,50,2,3,3,3,0
|
||||
21,100,0,50,52,2,3,1,0,0
|
||||
92,100,0,83,63,3,3,2,1,0
|
||||
20,100,1,43,34,0,3,2,2,0
|
||||
15,100,1,23,26,0,3,3,3,0
|
||||
45,100,1,12,67,0,3,1,0,0
|
||||
59,100,1,34,87,0,3,2,1,0
|
||||
32,100,0,32,90,0,3,3,2,0
|
||||
1,100,0,55,11,0,1,0,0,0
|
||||
2,100,0,44,12,1,1,0,1,0
|
||||
3,100,0,11,13,2,1,0,2,0
|
||||
4,100,0,34,66,3,0,0,3,0
|
||||
5,100,0,90,77,0,0,1,2,0
|
||||
6,100,0,89,88,0,0,2,2,0
|
||||
7,100,0,45,9,0,1,2,3,0
|
||||
8,100,0,34,22,3,1,2,3,0
|
||||
9,100,0,56,34,3,1,0,1,0
|
||||
10,100,0,78,5,3,0,3,1,0
|
||||
11,100,0,36,67,2,0,0,0,0
|
||||
12,100,0,57,23,2,1,1,0,0
|
||||
13,100,0,29,34,1,1,0,1,0
|
||||
14,100,0,30,90,1,1,2,2,0
|
||||
15,100,0,66,89,0,1,3,3,0
|
||||
1,6,0,5,10,4,1,1,3,1
|
||||
2,7,0,4,20,4,1,2,2,1
|
||||
3,4,0,11,30,4,1,3,1,1
|
||||
4,5,0,43,5,2,0,1,2,1
|
||||
5,6,0,9,17,2,0,2,1,1
|
||||
6,2,0,98,18,4,0,3,1,1
|
||||
7,11,0,54,19,4,1,0,2,1
|
||||
8,20,0,43,22,4,1,1,1,1
|
||||
9,30,0,65,43,4,1,2,3,1
|
||||
10,60,0,87,50,1,0,3,3,1
|
||||
11,80,0,63,76,1,0,0,2,1
|
||||
12,95,0,75,32,1,1,1,1,1
|
||||
13,76,0,30,43,2,1,2,0,1
|
||||
14,2,0,92,9,2,1,3,0,1
|
||||
1,6,0,5,10,4,3,1,3,0
|
||||
2,7,0,4,20,4,3,2,2,0
|
||||
3,4,0,11,30,4,3,3,1,0
|
||||
4,5,0,43,5,2,3,1,2,0
|
||||
5,6,0,9,17,2,3,2,1,0
|
||||
6,2,0,98,18,4,3,3,1,0
|
||||
7,11,0,54,19,4,3,0,2,0
|
||||
8,20,0,43,22,4,3,1,1,0
|
||||
9,30,0,65,43,4,3,2,3,0
|
||||
10,60,0,87,50,1,3,3,3,0
|
||||
11,80,0,63,76,1,3,0,2,0
|
||||
12,95,0,75,32,1,3,1,1,0
|
||||
13,76,0,30,43,2,3,2,0,0
|
||||
14,2,0,92,9,2,3,3,0,0
|
|
29
Drzewo.py
29
Drzewo.py
@ -1,29 +0,0 @@
|
||||
from sklearn import tree as skltree
|
||||
import pandas,os
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
atributes=['plant_water_level','growth','disease','fertility','tractor_water_level','temperature','rain','season','current_time'] #Columns in CSV file has to be in the same order
|
||||
class Drzewo:
|
||||
def __init__(self):
|
||||
self.tree=self.treeLearn()
|
||||
|
||||
def treeLearn(self):
|
||||
csvdata=pandas.read_csv('Data/dataTree2.csv')
|
||||
#csvdata = pandas.read_csv('Data/dataTree2.csv')
|
||||
x=csvdata[atributes]
|
||||
decision=csvdata['action']
|
||||
self.tree=skltree.DecisionTreeClassifier()
|
||||
self.tree=self.tree.fit(x.values,decision)
|
||||
|
||||
def plotTree(self):
|
||||
plt.figure(figsize=(20,30))
|
||||
skltree.plot_tree(self.tree,filled=True,feature_names=atributes)
|
||||
plt.title("Drzewo decyzyjne wytrenowane na przygotowanych danych: ")
|
||||
plt.savefig('tree.png')
|
||||
#plt.show()
|
||||
def makeDecision(self,values):
|
||||
action=self.tree.predict([values]) #0- nie podlewac, 1-podlewac
|
||||
if(action==[0]):
|
||||
return "Nie"
|
||||
if(action==[1]):
|
||||
return "Tak"
|
@ -1,139 +0,0 @@
|
||||
import json
|
||||
import random
|
||||
|
||||
from displayControler import NUM_Y, NUM_X
|
||||
|
||||
iterat = 2500
|
||||
population = 120
|
||||
roulette = True
|
||||
|
||||
plants = ['corn', 'potato', 'tomato', 'carrot']
|
||||
initial_yields = {'corn': 38, 'potato': 40, 'tomato': 43, 'carrot': 45}
|
||||
yield_reduction = {
|
||||
'corn': {'corn': -4.5, 'potato': -3, 'tomato': -7, 'carrot': -7},
|
||||
'potato': {'corn': -7, 'potato': -5, 'tomato': -10, 'carrot': -6},
|
||||
'tomato': {'corn': -4, 'potato': -5, 'tomato': -7, 'carrot': -7},
|
||||
'carrot': {'corn': -11, 'potato': -5, 'tomato': -4, 'carrot': -7}
|
||||
}
|
||||
yield_reduction2 = {
|
||||
'corn': {'corn': None, 'potato': -4, 'tomato': -2, 'carrot': -4},
|
||||
'potato': {'corn': None, 'potato': -5, 'tomato': -5, 'carrot': -2},
|
||||
'tomato': {'corn': -5, 'potato': -3, 'tomato': -7, 'carrot': None},
|
||||
'carrot': {'corn': -3, 'potato': -6, 'tomato': -4, 'carrot': -9}
|
||||
}
|
||||
yield_multiplier = {'corn': 1.25, 'potato': 1.17, 'tomato': 1.22, 'carrot': 1.13}
|
||||
yield_multiplier2 = {'corn': 1.25, 'potato': 1.19, 'tomato': 1.22, 'carrot': 1.15}
|
||||
|
||||
|
||||
def calculate_yields(garden):
|
||||
rows = len(garden)
|
||||
cols = len(garden[0])
|
||||
|
||||
total_yields = 0
|
||||
|
||||
for |