Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
8aadcfb677 | |||
831e599e14 | |||
c21203fb72 | |||
3fd1afdaeb | |||
4f5cf361ce | |||
e9c11d37d2 | |||
e77b8d03f9 | |||
8f0a1ed075 | |||
bd33fa3df5 | |||
5ca916873d | |||
361a733102 | |||
ef5c5556ef | |||
288d3cf30a | |||
7a14078390 | |||
19680a0139 | |||
301e05268c | |||
6c905621ca | |||
14795cdc5e | |||
3898a3bcab |
@ -1,5 +1,3 @@
|
|||||||
import random
|
|
||||||
|
|
||||||
import keyboard as keyboard
|
import keyboard as keyboard
|
||||||
|
|
||||||
import field as F
|
import field as F
|
||||||
@ -11,18 +9,20 @@ from src import mapschema as maps
|
|||||||
def genetic_algorithm_setup(field):
|
def genetic_algorithm_setup(field):
|
||||||
population_units = ["", "w", "p", "s"]
|
population_units = ["", "w", "p", "s"]
|
||||||
|
|
||||||
# new_population to be
|
# TODO REPREZENTACJA OSOBNIKA - MACIERZ ROZKłADU PLONÓW
|
||||||
population_text = []
|
population_text = []
|
||||||
|
population_text_single = []
|
||||||
|
|
||||||
|
population_size = 10
|
||||||
|
|
||||||
# Populate the population_text array
|
# Populate the population_text array
|
||||||
for row in range(D.GSIZE):
|
for k in range(population_size):
|
||||||
population_text.append([])
|
population_text_single = []
|
||||||
for column in range(D.GSIZE):
|
for row in range(D.GSIZE):
|
||||||
population_text[row].append(random.choice(population_units))
|
population_text_single.append([])
|
||||||
|
for column in range(D.GSIZE):
|
||||||
# printer
|
population_text_single[row].append(random.choice(population_units))
|
||||||
for _ in population_text:
|
population_text.append(population_text_single)
|
||||||
print(population_text)
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Genetic algorithm parameters:
|
Genetic algorithm parameters:
|
||||||
@ -31,75 +31,110 @@ def genetic_algorithm_setup(field):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# units per population in generation
|
# units per population in generation
|
||||||
sol_per_pop = 8
|
|
||||||
num_parents_mating = 4
|
|
||||||
|
|
||||||
population_values = []
|
|
||||||
fitness_row = []
|
|
||||||
|
|
||||||
# population Fitness
|
|
||||||
for i in range(0, D.GSIZE):
|
|
||||||
for j in range(D.GSIZE):
|
|
||||||
fitness_row.append(local_fitness(field, i, j, population_text))
|
|
||||||
population_values.append(fitness_row)
|
|
||||||
|
|
||||||
best_outputs = []
|
best_outputs = []
|
||||||
num_generations = 10
|
num_generations = 100
|
||||||
|
num_parents = 4
|
||||||
|
|
||||||
|
# iterative var
|
||||||
generation = 0
|
generation = 0
|
||||||
|
stop = 0
|
||||||
while generation < num_generations:
|
# TODO WARUNEK STOPU
|
||||||
|
while generation < num_generations and stop < 3:
|
||||||
if keyboard.is_pressed('space'):
|
if keyboard.is_pressed('space'):
|
||||||
generation += 1
|
generation += 1
|
||||||
|
|
||||||
print("Generation : ", generation)
|
print("Generation : ", generation)
|
||||||
# Measuring the fitness of each chromosome in the population.
|
# Measuring the fitness of each chromosome in the population.
|
||||||
|
|
||||||
fitness = cal_pop_fitness(population_values)
|
# population Fitness
|
||||||
|
fitness = []
|
||||||
|
|
||||||
|
for i in range(0, population_size):
|
||||||
|
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
||||||
|
|
||||||
print("Fitness")
|
print("Fitness")
|
||||||
print(fitness)
|
print(fitness)
|
||||||
|
|
||||||
# best_outputs.append(best_Output(new_population))
|
best = sorted(fitness, key=lambda tup: tup[1], reverse=True)[0:num_parents]
|
||||||
# The best result in the current iteration.
|
|
||||||
# print("Best result : ", best_Output(new_population))
|
|
||||||
|
|
||||||
|
# Leaderboard only
|
||||||
|
best_outputs.append(best[0][1])
|
||||||
|
|
||||||
|
# The best result in the current iteration.
|
||||||
|
print("Best result : ", best[0])
|
||||||
|
|
||||||
|
# TODO METODA WYBORU OSOBNIKA - RANKING
|
||||||
# Selecting the best parents in the population for mating.
|
# Selecting the best parents in the population for mating.
|
||||||
parents = select_mating_pool(new_population, fitness,
|
parents = [population_text[i[0]] for i in best]
|
||||||
num_parents_mating)
|
parents_copy = copy.deepcopy(parents)
|
||||||
print("Parents")
|
print("Parents")
|
||||||
print(parents)
|
for i in range(0, len(parents)):
|
||||||
|
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
||||||
|
for row in parents[i]]))
|
||||||
|
print("")
|
||||||
|
|
||||||
# Generating next generation using crossover.
|
# Generating next generation using crossover.
|
||||||
offspring_crossover = crossover(parents, offspring_size=(pop_size[0] - parents.shape[0], num_weights))
|
offspring_x = random.randint(1, D.GSIZE - 2)
|
||||||
|
offspring_y = random.randint(1, D.GSIZE - 2)
|
||||||
|
|
||||||
|
# TODO OPERATOR KRZYŻOWANIA
|
||||||
|
offspring_crossover = crossover(parents)
|
||||||
print("Crossover")
|
print("Crossover")
|
||||||
print(offspring_crossover)
|
for i in range(0, len(offspring_crossover)):
|
||||||
|
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
||||||
|
for row in offspring_crossover[i]]))
|
||||||
|
print("")
|
||||||
|
|
||||||
# Adding some variations to the offspring using mutation.
|
# TODO OPERATOR MUTACJI
|
||||||
offspring_mutation = mutation(offspring_crossover, num_mutations=2)
|
offspring_mutation = mutation(population_units, offspring_crossover, population_size - num_parents,
|
||||||
|
num_mutations=10)
|
||||||
print("Mutation")
|
print("Mutation")
|
||||||
print(offspring_mutation)
|
for i in range(0, len(offspring_mutation)):
|
||||||
|
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
|
||||||
|
for row in offspring_mutation[i]]))
|
||||||
|
print("")
|
||||||
|
|
||||||
# Creating the new population based on the parents and offspring.
|
population_text_copy = copy.deepcopy(population_text)
|
||||||
new_population[0:parents.shape[0], :] = parents
|
unused_indexes = [i for i in range(0, population_size) if i not in [j[0] for j in best]]
|
||||||
new_population[parents.shape[0]:, :] = offspring_mutation
|
# Creating next generation
|
||||||
|
population_text = []
|
||||||
|
for k in parents_copy:
|
||||||
|
population_text.append(k)
|
||||||
|
for k in range(0, len(offspring_mutation)):
|
||||||
|
population_text.append(offspring_mutation[k])
|
||||||
|
while len(population_text) < population_size:
|
||||||
|
x = random.choice(unused_indexes)
|
||||||
|
population_text.append(population_text_copy[x])
|
||||||
|
unused_indexes.remove(x)
|
||||||
|
|
||||||
# Getting the best solution after iterating finishing all generations.
|
# TODO WARUNEK STOPU
|
||||||
# At first, the fitness is calculated for each solution in the final generation.
|
stop = 0
|
||||||
fitness = cal_pop_fitness(new_population)
|
if generation > 10:
|
||||||
# Then return the index of that solution corresponding to the best fitness.
|
if best_outputs[-1] / best_outputs[-2] < 1.001:
|
||||||
best_match_idx = numpy.where(fitness == numpy.max(fitness))
|
stop += 1
|
||||||
|
if best_outputs[-1] / best_outputs[-3] < 1.001:
|
||||||
|
stop += 1
|
||||||
|
if best_outputs[-2] / best_outputs[-3] < 1.001:
|
||||||
|
stop += 1
|
||||||
|
|
||||||
print("Best solution : ", new_population[best_match_idx, :])
|
# final Fitness
|
||||||
print("Best solution fitness : ", fitness[best_match_idx])
|
fitness = []
|
||||||
|
for i in range(0, population_size):
|
||||||
|
fitness.append((i, population_fitness(population_text[i], field, population_size)))
|
||||||
|
|
||||||
import matplotlib.pyplot
|
print("Final Fitness")
|
||||||
|
print(fitness)
|
||||||
|
|
||||||
matplotlib.pyplot.plot(best_outputs)
|
best = sorted(fitness, key=lambda tup: tup[1])[0:num_parents]
|
||||||
matplotlib.pyplot.xlabel("Iteration")
|
|
||||||
matplotlib.pyplot.ylabel("Fitness")
|
|
||||||
matplotlib.pyplot.show()
|
|
||||||
|
|
||||||
# return best iteration of field
|
print("Best solution : ", )
|
||||||
|
for i in range(0, D.GSIZE):
|
||||||
|
print(population_text[best[0][0]][i])
|
||||||
|
print("Best solution fitness : ", best[0][1])
|
||||||
|
|
||||||
|
pretty_printer(best_outputs)
|
||||||
|
|
||||||
|
# TODO REALLY return best iteration of field
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,63 +1,47 @@
|
|||||||
import PIL
|
import torch
|
||||||
|
import torchvision
|
||||||
import torchvision.transforms as transforms
|
import torchvision.transforms as transforms
|
||||||
|
import torch.nn as nn
|
||||||
from AI import neural_network
|
import torch.nn.functional as F
|
||||||
|
import torch.optim as optim
|
||||||
|
import numpy as np
|
||||||
|
from matplotlib.pyplot import imshow
|
||||||
|
import os
|
||||||
|
import PIL
|
||||||
|
import numpy as np
|
||||||
|
from matplotlib.pyplot import imshow
|
||||||
|
import neural_network
|
||||||
|
from matplotlib.pyplot import imshow
|
||||||
|
|
||||||
|
|
||||||
# wcześniej grinder.py
|
# wcześniej grader.py
|
||||||
# Get accuracy for neural_network model 'network_model.pth'
|
# Get accuracy for neural_network model 'network_model.pth'
|
||||||
def NN_accuracy():
|
def NN_accuracy():
|
||||||
# Create the model
|
# Create the model
|
||||||
model = neural_network.Net()
|
net = neural_network.Net()
|
||||||
|
|
||||||
# Load state_dict
|
# Load state_dict
|
||||||
neural_network.load_network_from_structure(model)
|
neural_network.load_network_from_structure(net)
|
||||||
|
|
||||||
# Create the preprocessing transformation here
|
|
||||||
transform = transforms.Compose([neural_network.Negative(), transforms.ToTensor()])
|
|
||||||
|
|
||||||
# load your image(s)
|
|
||||||
img = PIL.Image.open('../src/test/0_100.jpg')
|
|
||||||
img2 = PIL.Image.open('../src/test/1_100.jpg')
|
|
||||||
img3 = PIL.Image.open('../src/test/4_100.jpg')
|
|
||||||
img4 = PIL.Image.open('../src/test/5_100.jpg')
|
|
||||||
|
|
||||||
# Transform
|
|
||||||
input = transform(img)
|
|
||||||
input2 = transform(img2)
|
|
||||||
input3 = transform(img3)
|
|
||||||
input4 = transform(img4)
|
|
||||||
|
|
||||||
# unsqueeze batch dimension, in case you are dealing with a single image
|
|
||||||
input = input.unsqueeze(0)
|
|
||||||
input2 = input2.unsqueeze(0)
|
|
||||||
input3 = input3.unsqueeze(0)
|
|
||||||
input4 = input4.unsqueeze(0)
|
|
||||||
|
|
||||||
# Set model to eval
|
# Set model to eval
|
||||||
model.eval()
|
net.eval()
|
||||||
|
|
||||||
# Get prediction
|
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
||||||
output = model(input)
|
|
||||||
output2 = model(input2)
|
|
||||||
output3 = model(input3)
|
|
||||||
output4 = model(input4)
|
|
||||||
|
|
||||||
print(output)
|
folderlist = os.listdir(os.path.dirname(__file__) + "\\test")
|
||||||
index = output.cpu().data.numpy().argmax()
|
|
||||||
print(index)
|
|
||||||
|
|
||||||
print(output2)
|
tested = 0
|
||||||
index = output2.cpu().data.numpy().argmax()
|
correct = 0
|
||||||
print(index)
|
|
||||||
|
|
||||||
print(output3)
|
for folder in folderlist:
|
||||||
index = output3.cpu().data.numpy().argmax()
|
for file in os.listdir(os.path.dirname(__file__) + "\\test\\" + folder):
|
||||||
print(index)
|
if neural_network.result_from_network(net, os.path.dirname(__file__) + "\\test\\" + folder + "\\" + file) == folder:
|
||||||
|
correct += 1
|
||||||
|
tested += 1
|
||||||
|
else:
|
||||||
|
tested += 1
|
||||||
|
|
||||||
print(output4)
|
print(correct/tested)
|
||||||
index = output4.cpu().data.numpy().argmax()
|
|
||||||
print(index)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
109
AI/ga_methods.py
109
AI/ga_methods.py
@ -1,3 +1,8 @@
|
|||||||
|
import copy
|
||||||
|
import random
|
||||||
|
|
||||||
|
import matplotlib
|
||||||
|
import matplotlib.pyplot
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
import src.dimensions as D
|
import src.dimensions as D
|
||||||
@ -5,88 +10,94 @@ import src.dimensions as D
|
|||||||
|
|
||||||
# Genetic Algorithm methods
|
# Genetic Algorithm methods
|
||||||
|
|
||||||
def local_fitness(field, x, y, plants):
|
def local_fitness(field, x, y, plants_case):
|
||||||
soil_value = 0
|
soil_value = 0
|
||||||
if field[x][y].field_type == "soil":
|
if field[x][y].field_type == "soil":
|
||||||
soil_value = 1
|
soil_value = 1
|
||||||
else:
|
else:
|
||||||
soil_value = 0.5
|
soil_value = 0.5
|
||||||
|
|
||||||
if plants[x][y] == "":
|
if plants_case[x][y] == "":
|
||||||
plant_value = 0
|
plant_value = 0
|
||||||
elif plants[x][y] == "w":
|
elif plants_case[x][y] == "w":
|
||||||
plant_value = 1
|
plant_value = 1
|
||||||
elif plants[x][y] == "p":
|
elif plants_case[x][y] == "p":
|
||||||
plant_value = 2
|
plant_value = 2
|
||||||
elif plants[x][y] == "s":
|
elif plants_case[x][y] == "s":
|
||||||
plant_value = 3
|
plant_value = 3
|
||||||
|
else:
|
||||||
|
plant_value = 1
|
||||||
|
|
||||||
neighbour_bonus = 1
|
neighbour_bonus = 1
|
||||||
|
|
||||||
if x - 1 >= 0:
|
if x - 1 >= 0:
|
||||||
if plants[x][y] == plants[x - 1][y]:
|
if plants_case[x][y] == plants_case[x - 1][y]:
|
||||||
neighbour_bonus += 1
|
neighbour_bonus += 1
|
||||||
if x + 1 < D.GSIZE:
|
if x + 1 < D.GSIZE:
|
||||||
if plants[x][y] == plants[x + 1][y]:
|
if plants_case[x][y] == plants_case[x + 1][y]:
|
||||||
neighbour_bonus += 1
|
neighbour_bonus += 1
|
||||||
if y - 1 >= 0:
|
if y - 1 >= 0:
|
||||||
if plants[x][y] == plants[x][y - 1]:
|
if plants_case[x][y] == plants_case[x][y - 1]:
|
||||||
neighbour_bonus += 1
|
neighbour_bonus += 1
|
||||||
if y + 1 < D.GSIZE:
|
if y + 1 < D.GSIZE:
|
||||||
if plants[x][y] == plants[x][y + 1]:
|
if plants_case[x][y] == plants_case[x][y + 1]:
|
||||||
neighbour_bonus += 1
|
neighbour_bonus += 1
|
||||||
|
|
||||||
# TODO * multiculture_bonus
|
|
||||||
local_fitness_value = (soil_value + plant_value) * (0.5 * neighbour_bonus + 1)
|
local_fitness_value = (soil_value + plant_value) * (0.5 * neighbour_bonus + 1)
|
||||||
return local_fitness_value
|
return local_fitness_value
|
||||||
|
|
||||||
|
|
||||||
def cal_pop_fitness(pop):
|
def population_fitness(population_text_local, field, population_size):
|
||||||
# Calculating the fitness value of each solution in the current population.
|
# Calculating the fitness value of each solution in the current population.
|
||||||
# The fitness function calulates the sum of products between each input and its corresponding weight.
|
# The fitness function calulates the sum of products between each input and its corresponding weight.
|
||||||
fitness = sum(map(sum, pop))
|
fitness = []
|
||||||
|
|
||||||
|
for k in range(population_size):
|
||||||
|
population_values_single = []
|
||||||
|
population_values_single_row = []
|
||||||
|
fitness_row = []
|
||||||
|
|
||||||
|
for i in range(0, D.GSIZE):
|
||||||
|
for j in range(0, D.GSIZE):
|
||||||
|
population_values_single_row.append(local_fitness(field, i, j, population_text_local))
|
||||||
|
population_values_single.append(population_values_single_row)
|
||||||
|
|
||||||
|
for i in range(D.GSIZE):
|
||||||
|
fitness_row.append(sum(population_values_single[i]))
|
||||||
|
fitness = sum(fitness_row)
|
||||||
return fitness
|
return fitness
|
||||||
|
|
||||||
|
|
||||||
def select_mating_pool(pop, fitness, num_parents):
|
def crossover(local_parents):
|
||||||
# Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
|
ret = []
|
||||||
parents = numpy.empty((num_parents, pop.shape[1]))
|
for i in range(0, len(local_parents)):
|
||||||
for parent_num in range(num_parents):
|
child = copy.deepcopy(local_parents[i])
|
||||||
max_fitness_idx = numpy.where(fitness == numpy.max(fitness))
|
# Vertical randomization
|
||||||
max_fitness_idx = max_fitness_idx[0][0]
|
width = random.randint(1, D.GSIZE // len(local_parents)) # width of stripes
|
||||||
parents[parent_num, :] = pop[max_fitness_idx, :]
|
indexes_parents = numpy.random.permutation(range(0, len(local_parents))) # sorting of stripes
|
||||||
fitness[max_fitness_idx] = -99999999999
|
beginning = random.randint(0, len(local_parents[0]) - width * len(
|
||||||
return parents
|
local_parents)) # point we start putting the stripes from
|
||||||
|
for x in indexes_parents:
|
||||||
|
child[beginning:beginning + width] = local_parents[x][beginning:beginning + width]
|
||||||
|
beginning += width
|
||||||
|
ret.append(child)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def crossover(parents, offspring_size):
|
def mutation(population_units, offspring_crossover, num_mutants, num_mutations=10):
|
||||||
offspring = numpy.empty(offspring_size)
|
for case in range(0, len(offspring_crossover)):
|
||||||
# The point at which crossover takes place between two parents. Usually, it is at the center.
|
for mutation in range(0, num_mutations):
|
||||||
crossover_point = numpy.uint8(offspring_size[1] / 2)
|
mutation_x = random.randint(0, D.GSIZE - 1)
|
||||||
|
mutation_y = random.randint(0, D.GSIZE - 1)
|
||||||
|
mutation_value = random.choice(population_units)
|
||||||
|
offspring_crossover[case][mutation_x][mutation_y] = mutation_value
|
||||||
|
num_mutants -= 1
|
||||||
|
|
||||||
for k in range(offspring_size[0]):
|
|
||||||
# Index of the first parent to mate.
|
|
||||||
parent1_idx = k % parents.shape[0]
|
|
||||||
# Index of the second parent to mate.
|
|
||||||
parent2_idx = (k + 1) % parents.shape[0]
|
|
||||||
# The new offspring will have its first half of its genes taken from the first parent.
|
|
||||||
offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]
|
|
||||||
# The new offspring will have its second half of its genes taken from the second parent.
|
|
||||||
offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]
|
|
||||||
return offspring
|
|
||||||
|
|
||||||
|
|
||||||
def mutation(offspring_crossover, num_mutations=1):
|
|
||||||
mutations_counter = numpy.uint8(offspring_crossover.shape[1] / num_mutations)
|
|
||||||
# Mutation changes a number of genes as defined by the num_mutations argument. The changes are random.
|
|
||||||
for idx in range(offspring_crossover.shape[0]):
|
|
||||||
gene_idx = mutations_counter - 1
|
|
||||||
for mutation_num in range(num_mutations):
|
|
||||||
# The random value to be added to the gene.
|
|
||||||
random_value = numpy.random.uniform(-1.0, 1.0, 1)
|
|
||||||
offspring_crossover[idx, gene_idx] = offspring_crossover[idx, gene_idx] + random_value
|
|
||||||
gene_idx = gene_idx + mutations_counter
|
|
||||||
return offspring_crossover
|
return offspring_crossover
|
||||||
|
|
||||||
|
|
||||||
def best_Output(new_population):
|
def pretty_printer(best_outputs):
|
||||||
return numpy.max(numpy.sum(new_population * equation_inputs, axis=1))
|
matplotlib.pyplot.plot(best_outputs)
|
||||||
|
matplotlib.pyplot.xlabel("Iteration")
|
||||||
|
matplotlib.pyplot.ylabel("Fitness")
|
||||||
|
matplotlib.pyplot.show()
|
||||||
|
@ -1,69 +1,76 @@
|
|||||||
import PIL
|
|
||||||
import numpy as np
|
|
||||||
import torch
|
import torch
|
||||||
import torch.nn as nn
|
|
||||||
import torch.optim as optim
|
|
||||||
import torchvision
|
import torchvision
|
||||||
import torchvision.transforms as transforms
|
import torchvision.transforms as transforms
|
||||||
|
import torch.nn as nn
|
||||||
|
import torch.nn.functional as F
|
||||||
|
import torch.optim as optim
|
||||||
|
import numpy as np
|
||||||
|
from matplotlib.pyplot import imshow
|
||||||
|
import os
|
||||||
|
import PIL
|
||||||
|
import numpy as np
|
||||||
from matplotlib.pyplot import imshow
|
from matplotlib.pyplot import imshow
|
||||||
|
|
||||||
|
|
||||||
def to_negative(img):
|
def to_negative(img):
|
||||||
img = PIL.ImageOps.invert(img)
|
img = PIL.ImageOps.invert(img)
|
||||||
return img
|
return img
|
||||||
|
|
||||||
|
|
||||||
class Negative(object):
|
class Negative(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __call__(self, img):
|
def __call__(self, img):
|
||||||
return to_negative(img)
|
return to_negative(img)
|
||||||
|
|
||||||
|
|
||||||
def plotdigit(image):
|
|
||||||
img = np.reshape(image, (-1, 100))
|
|
||||||
imshow(img, cmap='Greys')
|
|
||||||
|
|
||||||
|
|
||||||
transform = transforms.Compose([Negative(), transforms.ToTensor()])
|
transform = transforms.Compose([Negative(), transforms.ToTensor()])
|
||||||
train_set = torchvision.datasets.ImageFolder(root='../src/train', transform=transform)
|
train_set = torchvision.datasets.ImageFolder(root='train', transform=transform)
|
||||||
classes = ("apple", "potato")
|
classes = ("pepper", "potato", "strawberry", "tomato")
|
||||||
|
|
||||||
BATCH_SIZE = 2
|
BATCH_SIZE = 4
|
||||||
train_loader = torch.utils.data.DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True, num_workers=0)
|
train_loader = torch.utils.data.DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True, num_workers=0)
|
||||||
|
|
||||||
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
|
|
||||||
class Net(nn.Module):
|
class Net(nn.Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Net, self).__init__()
|
super().__init__()
|
||||||
self.flatten = nn.Flatten()
|
self.network = nn.Sequential(
|
||||||
self.linear_relu_stack = nn.Sequential(
|
nn.Conv2d(3, 32, kernel_size=3, padding=1), #3 channels to 32 channels
|
||||||
nn.Linear(3 * 100 * 100, 512),
|
|
||||||
nn.ReLU(),
|
nn.ReLU(),
|
||||||
nn.Linear(512, 512),
|
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
|
||||||
nn.ReLU(),
|
nn.ReLU(),
|
||||||
nn.Linear(512, 2),
|
nn.MaxPool2d(2, 2), # output: 64 channels x 50 x 50 image size - decrease
|
||||||
nn.ReLU()
|
|
||||||
)
|
|
||||||
self.linear_relu_stack = self.linear_relu_stack.to(device)
|
|
||||||
|
|
||||||
def forward(self, x):
|
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
|
||||||
x = self.flatten(x).to(device)
|
nn.ReLU(),
|
||||||
logits = self.linear_relu_stack(x).to(device)
|
nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1), #increase power of model
|
||||||
return logits
|
nn.ReLU(),
|
||||||
|
nn.MaxPool2d(2, 2), # output: 128 x 25 x 25
|
||||||
|
|
||||||
|
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.MaxPool2d(5, 5), # output: 256 x 5 x 5
|
||||||
|
|
||||||
|
nn.Flatten(), #a single vector 256*5*5,
|
||||||
|
nn.Linear(256*5*5, 1024),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Linear(1024, 512),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Linear(512, 4))
|
||||||
|
|
||||||
|
def forward(self, xb):
|
||||||
|
return self.network(xb)
|
||||||
|
|
||||||
def training_network():
|
def training_network():
|
||||||
net = Net()
|
net = Net()
|
||||||
net = net.to(device)
|
net = net.to(device)
|
||||||
|
|
||||||
criterion = nn.CrossEntropyLoss()
|
criterion = nn.CrossEntropyLoss()
|
||||||
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
|
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
|
||||||
|
|
||||||
for epoch in range(4):
|
for epoch in range(10):
|
||||||
running_loss = 0.0
|
running_loss = 0.0
|
||||||
for i, data in enumerate(train_loader, 0):
|
for i, data in enumerate(train_loader, 0):
|
||||||
inputs, labels = data[0].to(device), data[1].to(device)
|
inputs, labels = data[0].to(device), data[1].to(device)
|
||||||
@ -72,34 +79,33 @@ def training_network():
|
|||||||
loss = criterion(outputs, labels)
|
loss = criterion(outputs, labels)
|
||||||
loss.backward()
|
loss.backward()
|
||||||
optimizer.step()
|
optimizer.step()
|
||||||
|
|
||||||
running_loss += loss.item()
|
running_loss += loss.item()
|
||||||
if i % 2000 == 1999:
|
if i % 200 == 199:
|
||||||
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss))
|
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss))
|
||||||
running_loss = 0.0
|
running_loss = 0.0
|
||||||
|
|
||||||
print("Finished training")
|
print("Finished training")
|
||||||
save_network_to_file(net)
|
save_network_to_file(net)
|
||||||
|
|
||||||
|
|
||||||
def result_from_network(net, loaded_image):
|
def result_from_network(net, loaded_image):
|
||||||
image = PIL.Image.open(loaded_image)
|
image = PIL.Image.open(loaded_image)
|
||||||
pil_to_tensor = transforms.ToTensor()(image.convert("RGB")).unsqueeze_(0)
|
pil_to_tensor = transforms.Compose([Negative(), transforms.ToTensor()])(image.convert("RGB")).unsqueeze_(0)
|
||||||
outputs = net(pil_to_tensor.to(device))
|
outputs = net(pil_to_tensor)
|
||||||
|
|
||||||
return classes[torch.max(outputs, 1)[1]]
|
return classes[torch.max(outputs, 1)[1]]
|
||||||
|
|
||||||
|
|
||||||
def save_network_to_file(network):
|
def save_network_to_file(network):
|
||||||
torch.save(network.state_dict(), 'network_model.pth')
|
torch.save(network.state_dict(), 'network_model.pth')
|
||||||
print("Network saved to file")
|
print("Network saved to file")
|
||||||
|
|
||||||
|
|
||||||
def load_network_from_structure(network):
|
def load_network_from_structure(network):
|
||||||
network.load_state_dict(torch.load('network_model.pth'))
|
network.load_state_dict(torch.load('network_model.pth'))
|
||||||
|
|
||||||
|
|
||||||
# Create network_model.pth
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print(torch.cuda.is_available())
|
print(torch.cuda.is_available())
|
||||||
training_network()
|
training_network()
|
66
field.py
66
field.py
@ -1,9 +1,7 @@
|
|||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from src.colors import *
|
from src.colors import *
|
||||||
from src.dimensions import *
|
from src.dimensions import *
|
||||||
|
|
||||||
|
|
||||||
class Field(pygame.sprite.Sprite):
|
class Field(pygame.sprite.Sprite):
|
||||||
def __init__(self, row, column, field_type):
|
def __init__(self, row, column, field_type):
|
||||||
super(Field, self).__init__()
|
super(Field, self).__init__()
|
||||||
@ -26,22 +24,62 @@ class Field(pygame.sprite.Sprite):
|
|||||||
self.position = [row, column]
|
self.position = [row, column]
|
||||||
self.hydration = 0
|
self.hydration = 0
|
||||||
self.planted = 0
|
self.planted = 0
|
||||||
self.fertility = 1
|
self.fertility = 0
|
||||||
self.tractor_there = False
|
self.tractor_there = False
|
||||||
|
|
||||||
def hydrate(self):
|
def hydrate(self):
|
||||||
if self.field_type == "soil" and self.hydration <= 5:
|
if self.field_type == "soil" and self.hydration <= 5:
|
||||||
self.hydration += 1
|
self.hydration += 1
|
||||||
|
if self.fertility == 1:
|
||||||
# color field to it's hydration value
|
if self.hydration == 0:
|
||||||
self.surf.fill(eval('BROWN' + str(self.hydration)))
|
self.surf.fill(REDDISH0)
|
||||||
|
self.fertility = 0
|
||||||
|
if self.hydration == 1:
|
||||||
|
self.surf.fill(REDDISH1)
|
||||||
|
if self.hydration == 2:
|
||||||
|
self.surf.fill(REDDISH2)
|
||||||
|
if self.hydration == 3:
|
||||||
|
self.surf.fill(REDDISH3)
|
||||||
|
if self.hydration == 4 or self.hydration == 5:
|
||||||
|
self.surf.fill(REDDISH4)
|
||||||
|
else:
|
||||||
|
if self.hydration == 0:
|
||||||
|
self.surf.fill(BROWN0)
|
||||||
|
if self.hydration == 1:
|
||||||
|
self.surf.fill(BROWN1)
|
||||||
|
if self.hydration == 2:
|
||||||
|
self.surf.fill(BROWN2)
|
||||||
|
if self.hydration == 3:
|
||||||
|
self.surf.fill(BROWN3)
|
||||||
|
if self.hydration == 4 or self.hydration == 5:
|
||||||
|
self.surf.fill(BROWN4)
|
||||||
|
|
||||||
def dehydrate(self):
|
def dehydrate(self):
|
||||||
if self.field_type == "soil" and self.hydration > 0:
|
if self.field_type == "soil" and self.hydration > 0:
|
||||||
self.hydration -= 1
|
self.hydration -= 1
|
||||||
|
if self.fertility == 1:
|
||||||
# color field to it's hydration value
|
if self.hydration == 0:
|
||||||
self.surf.fill(eval('BROWN' + str(self.hydration)))
|
self.surf.fill(REDDISH0)
|
||||||
|
self.fertility = 0
|
||||||
|
if self.hydration == 1:
|
||||||
|
self.surf.fill(REDDISH1)
|
||||||
|
if self.hydration == 2:
|
||||||
|
self.surf.fill(REDDISH2)
|
||||||
|
if self.hydration == 3:
|
||||||
|
self.surf.fill(REDDISH3)
|
||||||
|
if self.hydration == 4 or self.hydration == 5:
|
||||||
|
self.surf.fill(REDDISH4)
|
||||||
|
else:
|
||||||
|
if self.hydration == 0:
|
||||||
|
self.surf.fill(BROWN0)
|
||||||
|
if self.hydration == 1:
|
||||||
|
self.surf.fill(BROWN1)
|
||||||
|
if self.hydration == 2:
|
||||||
|
self.surf.fill(BROWN2)
|
||||||
|
if self.hydration == 3:
|
||||||
|
self.surf.fill(BROWN3)
|
||||||
|
if self.hydration == 4 or self.hydration == 5:
|
||||||
|
self.surf.fill(BROWN4)
|
||||||
|
|
||||||
def free(self):
|
def free(self):
|
||||||
self.planted = 0
|
self.planted = 0
|
||||||
|
43
main.py
43
main.py
@ -10,12 +10,15 @@ from pygame.locals import (
|
|||||||
QUIT
|
QUIT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Import other files from project
|
# Import other files from project
|
||||||
import field as F
|
import field as F
|
||||||
import node as N
|
import node as N
|
||||||
import plant as P
|
import plant as P
|
||||||
import src.colors as C
|
import src.colors as C
|
||||||
import src.dimensions as D
|
import src.dimensions as D
|
||||||
|
import AI.GeneticAlgorithm as ga
|
||||||
|
import AI.neural_network as nn
|
||||||
import tractor as T
|
import tractor as T
|
||||||
from src import mapschema as maps
|
from src import mapschema as maps
|
||||||
|
|
||||||
@ -44,6 +47,16 @@ if __name__ == "__main__":
|
|||||||
field[row].append(fieldbit)
|
field[row].append(fieldbit)
|
||||||
|
|
||||||
# genetic_algorithm_setup(field)
|
# genetic_algorithm_setup(field)
|
||||||
|
num_of_plants = 0
|
||||||
|
plant_pops = []
|
||||||
|
best_plant_pop = []
|
||||||
|
|
||||||
|
goal_gen = 100
|
||||||
|
best_plant_pop, plant_pops, num_of_plants, fitness = ga.genetic_algorithm_setup(field, plant_pops, goal_gen)
|
||||||
|
|
||||||
|
net = nn.Net()
|
||||||
|
nn.load_network_from_structure(net)
|
||||||
|
net.eval()
|
||||||
|
|
||||||
# Create Tractor object
|
# Create Tractor object
|
||||||
tractor = T.Tractor(field, [0, 0])
|
tractor = T.Tractor(field, [0, 0])
|
||||||
@ -58,9 +71,11 @@ if __name__ == "__main__":
|
|||||||
for row in range(D.GSIZE):
|
for row in range(D.GSIZE):
|
||||||
plants.append([])
|
plants.append([])
|
||||||
for column in range(D.GSIZE):
|
for column in range(D.GSIZE):
|
||||||
if mapschema[column][row] != 0:
|
if best_plant_pop[column][row] != "":
|
||||||
plantbit = P.Plant(field[row][column], mapschema[column][row])
|
plantbit = P.Plant(field[row][column], best_plant_pop[column][row])
|
||||||
plants[row].append(plantbit)
|
plants[row].append(plantbit)
|
||||||
|
else:
|
||||||
|
plants[row].append(0)
|
||||||
|
|
||||||
# Create list for tractor instructions
|
# Create list for tractor instructions
|
||||||
path = []
|
path = []
|
||||||
@ -77,7 +92,6 @@ if __name__ == "__main__":
|
|||||||
# Main loop
|
# Main loop
|
||||||
while RUNNING:
|
while RUNNING:
|
||||||
|
|
||||||
# Look at every event in the queue
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
# Did the user hit a key?
|
# Did the user hit a key?
|
||||||
if event.type == KEYDOWN:
|
if event.type == KEYDOWN:
|
||||||
@ -105,19 +119,11 @@ if __name__ == "__main__":
|
|||||||
tractor.rotate_right()
|
tractor.rotate_right()
|
||||||
elif path[0] == "hydrate":
|
elif path[0] == "hydrate":
|
||||||
tractor.hydrate(field)
|
tractor.hydrate(field)
|
||||||
|
elif path[0] == "fertilize":
|
||||||
|
if plants[tractor.position[1]][tractor.position[0]]:
|
||||||
|
tractor.fertilize(field, plants, nn.result_from_network(net, plants[tractor.position[0]][tractor.position[1]].testimage))
|
||||||
path.pop(0)
|
path.pop(0)
|
||||||
|
|
||||||
# Get all keys pressed at a time CURRENTLY UNUSED
|
|
||||||
pressed_keys = pygame.key.get_pressed()
|
|
||||||
|
|
||||||
# control tractor with pressed keys CURRENTLY UNUSED
|
|
||||||
if pressed_keys[K_UP]:
|
|
||||||
tractor.move()
|
|
||||||
elif pressed_keys[K_LEFT]:
|
|
||||||
tractor.rotate_left()
|
|
||||||
elif pressed_keys[K_RIGHT]:
|
|
||||||
tractor.rotate_right()
|
|
||||||
|
|
||||||
# Set the screen background
|
# Set the screen background
|
||||||
screen.fill(C.DBROWN)
|
screen.fill(C.DBROWN)
|
||||||
@ -133,9 +139,10 @@ if __name__ == "__main__":
|
|||||||
# Plants grow with every 10th tick, then they are drawn
|
# Plants grow with every 10th tick, then they are drawn
|
||||||
for row in plants:
|
for row in plants:
|
||||||
for plant in row:
|
for plant in row:
|
||||||
plant.tick()
|
if plant != 0:
|
||||||
plant.grow()
|
plant.tick()
|
||||||
screen.blit(plant.surf, plant.rect)
|
plant.grow()
|
||||||
|
screen.blit(plant.surf, plant.rect)
|
||||||
|
|
||||||
# Field are drying with every 100th tick
|
# Field are drying with every 100th tick
|
||||||
if TICKER == 0:
|
if TICKER == 0:
|
||||||
@ -150,4 +157,4 @@ if __name__ == "__main__":
|
|||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
# Ensure program maintains a stable framerate
|
# Ensure program maintains a stable framerate
|
||||||
clock.tick(8)
|
clock.tick(35)
|
||||||
|
56
node.py
56
node.py
@ -137,10 +137,12 @@ class Node:
|
|||||||
closedList.append(currentNode)
|
closedList.append(currentNode)
|
||||||
|
|
||||||
if currentNode.field[currentNode.position[0]][currentNode.position[1]].planted and \
|
if currentNode.field[currentNode.position[0]][currentNode.position[1]].planted and \
|
||||||
|
currentNode.field[currentNode.position[0]][currentNode.position[1]].field_type == "soil" and \
|
||||||
currentNode.field[currentNode.position[0]][currentNode.position[1]].hydration < 2:
|
currentNode.field[currentNode.position[0]][currentNode.position[1]].hydration < 2:
|
||||||
path = []
|
path = []
|
||||||
for _ in range(currentNode.field[currentNode.position[0]][currentNode.position[1]].hydration, 4):
|
for _ in range(currentNode.field[currentNode.position[0]][currentNode.position[1]].hydration, 4):
|
||||||
path.append("hydrate")
|
path.append("hydrate")
|
||||||
|
path.append("fertilize")
|
||||||
current = currentNode
|
current = currentNode
|
||||||
while current is not None:
|
while current is not None:
|
||||||
path.append(current.action)
|
path.append(current.action)
|
||||||
@ -174,3 +176,57 @@ class Node:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
heapq.heappush(openList, child)
|
heapq.heappush(openList, child)
|
||||||
|
|
||||||
|
def findPathToPlantSpot(self, goals):
|
||||||
|
startNode = Node(self.field, self.position, self.rotation)
|
||||||
|
|
||||||
|
openList = []
|
||||||
|
closedList = []
|
||||||
|
|
||||||
|
startNode.parent = None
|
||||||
|
|
||||||
|
heapq.heappush(openList, startNode)
|
||||||
|
|
||||||
|
while len(openList) > 0:
|
||||||
|
currentNode = heapq.heappop(openList)
|
||||||
|
|
||||||
|
closedList.append(currentNode)
|
||||||
|
|
||||||
|
if not currentNode.field[currentNode.position[0]][currentNode.position[1]].planted and \
|
||||||
|
goals[currentNode.position[0]][currentNode.position[1]] != "":
|
||||||
|
path = []
|
||||||
|
path.append("plant")
|
||||||
|
current = currentNode
|
||||||
|
while current is not None:
|
||||||
|
path.append(current.action)
|
||||||
|
current = current.parent
|
||||||
|
return path[::-1]
|
||||||
|
|
||||||
|
children = succesor(currentNode)
|
||||||
|
|
||||||
|
perm = 0
|
||||||
|
for child in children:
|
||||||
|
for closedChild in closedList:
|
||||||
|
if child.position == closedChild.position and child.rotation == closedChild.rotation and child.action == closedChild.action:
|
||||||
|
perm = 1
|
||||||
|
break
|
||||||
|
if perm == 1:
|
||||||
|
perm = 0
|
||||||
|
continue
|
||||||
|
child.parent = currentNode
|
||||||
|
child.startCost = currentNode.startCost + child.field[child.position[0]][child.position[1]].moveCost
|
||||||
|
child.heuristic = abs(startNode.position[0] - child.position[0]) + abs(
|
||||||
|
startNode.position[1] - child.position[1])
|
||||||
|
child.totalCost = child.startCost + child.heuristic
|
||||||
|
|
||||||
|
for openNode in openList:
|
||||||
|
if child.position == openNode.position and child.rotation == openNode.rotation and child.action == openNode.action and child.startCost >= openNode.startCost:
|
||||||
|
perm = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
if perm == 1:
|
||||||
|
perm = 0
|
||||||
|
continue
|
||||||
|
|
||||||
|
heapq.heappush(openList, child)
|
||||||
|
|
||||||
|
110
plant.py
110
plant.py
@ -1,29 +1,32 @@
|
|||||||
|
import os
|
||||||
|
import random
|
||||||
|
|
||||||
from AI.decision_tree import *
|
from AI.decision_tree import *
|
||||||
from src.dimensions import *
|
from src.dimensions import *
|
||||||
from src.sprites import *
|
from src.sprites import *
|
||||||
|
from src.colors import *
|
||||||
|
|
||||||
|
path = os.path.dirname(__file__) + "\\src\\test\\"
|
||||||
|
|
||||||
class Plant(pygame.sprite.Sprite):
|
class Plant(pygame.sprite.Sprite):
|
||||||
def __init__(self, field, species):
|
def __init__(self, field, species):
|
||||||
super(Plant, self).__init__()
|
|
||||||
self.species = species
|
self.species = species
|
||||||
if self.species == "wheat":
|
if self.species == "tomato":
|
||||||
self.growth_speed = 1.5
|
|
||||||
self.humidity_needed = 2
|
|
||||||
self.img0 = wheat_img_0
|
self.img0 = wheat_img_0
|
||||||
self.img1 = wheat_img_1
|
self.img1 = wheat_img_1
|
||||||
self.img2 = wheat_img_2
|
self.img2 = wheat_img_2
|
||||||
self.img3 = wheat_img_3
|
self.img3 = wheat_img_3
|
||||||
elif self.species == "potato":
|
elif self.species == "potato":
|
||||||
self.growth_speed = 1
|
|
||||||
self.humidity_needed = 1
|
|
||||||
self.img0 = potato_img_0
|
self.img0 = potato_img_0
|
||||||
self.img1 = potato_img_1
|
self.img1 = potato_img_1
|
||||||
self.img2 = potato_img_2
|
self.img2 = potato_img_2
|
||||||
self.img3 = potato_img_3
|
self.img3 = potato_img_3
|
||||||
elif self.species == "strawberry":
|
elif self.species == "strawberry":
|
||||||
self.growth_speed = 0.8
|
self.img0 = strawberry_img_0
|
||||||
self.humidity_needed = 1
|
self.img1 = strawberry_img_1
|
||||||
|
self.img2 = strawberry_img_2
|
||||||
|
self.img3 = strawberry_img_3
|
||||||
|
elif self.species == "pepper":
|
||||||
self.img0 = strawberry_img_0
|
self.img0 = strawberry_img_0
|
||||||
self.img1 = strawberry_img_1
|
self.img1 = strawberry_img_1
|
||||||
self.img2 = strawberry_img_2
|
self.img2 = strawberry_img_2
|
||||||
@ -38,9 +41,94 @@ class Plant(pygame.sprite.Sprite):
|
|||||||
field.planted = True
|
field.planted = True
|
||||||
self.tickscount = 0
|
self.tickscount = 0
|
||||||
self.ticks = 0
|
self.ticks = 0
|
||||||
|
self.path = path + self.species + "\\"
|
||||||
|
self.testimage = self.path + random.choice(os.listdir(self.path))
|
||||||
|
|
||||||
def dtree(self):
|
def dtree(self):
|
||||||
decision_tree(self)
|
if self.field.hydration == 4:
|
||||||
|
if self.is_healthy == 1:
|
||||||
|
if self.field.tractor_there == 0:
|
||||||
|
if self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.ticks == 1:
|
||||||
|
return 1
|
||||||
|
elif self.field.tractor_there == 1:
|
||||||
|
return 0
|
||||||
|
elif self.is_healthy == 0:
|
||||||
|
return 0
|
||||||
|
elif self.field.hydration == 2:
|
||||||
|
if self.species == "pepper":
|
||||||
|
if self.ticks == 1:
|
||||||
|
if self.is_healthy == 1:
|
||||||
|
return 1
|
||||||
|
elif self.is_healthy == 0:
|
||||||
|
return 0
|
||||||
|
elif self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.species == "potato":
|
||||||
|
return 0
|
||||||
|
elif self.species == "tomato":
|
||||||
|
return 0
|
||||||
|
elif self.species == "strawberry":
|
||||||
|
return 0
|
||||||
|
elif self.field.hydration == 1:
|
||||||
|
if self.species == "potato":
|
||||||
|
return 0
|
||||||
|
elif self.species == "strawberry":
|
||||||
|
if self.ticks == 1:
|
||||||
|
return -1
|
||||||
|
elif self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.species == "tomato":
|
||||||
|
return 0
|
||||||
|
elif self.species == "pepper":
|
||||||
|
if self.is_healthy == 0:
|
||||||
|
return 0
|
||||||
|
elif self.is_healthy == 1:
|
||||||
|
if self.field.tractor_there == 0:
|
||||||
|
if self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.ticks == 1:
|
||||||
|
return 1
|
||||||
|
elif self.field.tractor_there == 1:
|
||||||
|
return 0
|
||||||
|
elif self.field.hydration == 3:
|
||||||
|
if self.ticks == 1:
|
||||||
|
if self.field.tractor_there == 0:
|
||||||
|
if self.is_healthy == 1:
|
||||||
|
if self.species == "potato":
|
||||||
|
if self.field.fertility == 1:
|
||||||
|
return 1
|
||||||
|
elif self.field.fertility == 0:
|
||||||
|
return 0
|
||||||
|
elif self.species == "strawberry":
|
||||||
|
return 1
|
||||||
|
elif self.species == "pepper":
|
||||||
|
return 1
|
||||||
|
elif self.species == "tomato":
|
||||||
|
return 1
|
||||||
|
elif self.is_healthy == 0:
|
||||||
|
return 0
|
||||||
|
elif self.field.tractor_there == 1:
|
||||||
|
return 0
|
||||||
|
elif self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.field.hydration == 5:
|
||||||
|
if self.field.tractor_there == 1:
|
||||||
|
return 0
|
||||||
|
elif self.field.tractor_there == 0:
|
||||||
|
if self.is_healthy == 0:
|
||||||
|
return 0
|
||||||
|
elif self.is_healthy == 1:
|
||||||
|
if self.ticks == 1:
|
||||||
|
return 1
|
||||||
|
elif self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.field.hydration == 0:
|
||||||
|
if self.ticks == 0:
|
||||||
|
return 0
|
||||||
|
elif self.ticks == 1:
|
||||||
|
return -1
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if self.growth == 0:
|
if self.growth == 0:
|
||||||
@ -63,6 +151,7 @@ class Plant(pygame.sprite.Sprite):
|
|||||||
self.growth = 4
|
self.growth = 4
|
||||||
if self.growth < 0:
|
if self.growth < 0:
|
||||||
self.growth = 0
|
self.growth = 0
|
||||||
|
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
@ -70,3 +159,6 @@ class Plant(pygame.sprite.Sprite):
|
|||||||
if self.tickscount >= 25:
|
if self.tickscount >= 25:
|
||||||
self.tickscount = 0
|
self.tickscount = 0
|
||||||
self.ticks = 1
|
self.ticks = 1
|
||||||
|
|
||||||
|
def remove(self):
|
||||||
|
self.field.planted = False
|
||||||
|
@ -7,6 +7,14 @@ BROWN2 = (140, 110, 55)
|
|||||||
BROWN3 = (110, 85, 40)
|
BROWN3 = (110, 85, 40)
|
||||||
BROWN4 = (80, 60, 20)
|
BROWN4 = (80, 60, 20)
|
||||||
BROWN5 = (80, 60, 20)
|
BROWN5 = (80, 60, 20)
|
||||||
|
|
||||||
|
REDDISH0 = (230, 150, 90)
|
||||||
|
REDDISH1 = (210, 130, 70)
|
||||||
|
REDDISH2 = (190, 110, 55)
|
||||||
|
REDDISH3 = (160, 85, 40)
|
||||||
|
REDDISH4 = (130, 60, 20)
|
||||||
|
REDDISH5 = (130, 60, 20)
|
||||||
|
|
||||||
DBROWN = (65, 50, 20)
|
DBROWN = (65, 50, 20)
|
||||||
LBROWN = (108, 97, 62)
|
LBROWN = (108, 97, 62)
|
||||||
BLUE = (18, 93, 156)
|
BLUE = (18, 93, 156)
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
GSIZE = 10
|
GSIZE = 10
|
||||||
|
|
||||||
# This sets the WIDTH and HEIGHT of each grid location
|
# This sets the WIDTH and HEIGHT of each grid location
|
||||||
WIDTH = 35
|
WIDTH = 80
|
||||||
HEIGHT = 35
|
HEIGHT = 80
|
||||||
|
|
||||||
# This sets the margin between each cell
|
# This sets the margin between each cell
|
||||||
MARGIN = 5
|
MARGIN = 5
|
||||||
|
|
||||||
# Window size
|
# Window size
|
||||||
SCREEN_WIDTH = GSIZE * (WIDTH + MARGIN) + MARGIN
|
SCREEN_WIDTH = GSIZE * (WIDTH + MARGIN) + MARGIN
|
||||||
SCREEN_HEIGHT = GSIZE * (HEIGHT + MARGIN) + MARGIN
|
SCREEN_HEIGHT = GSIZE * (HEIGHT + MARGIN) + MARGIN + 100
|
||||||
|
18
tractor.py
18
tractor.py
@ -1,7 +1,6 @@
|
|||||||
from pygame.locals import (K_c)
|
|
||||||
|
|
||||||
from src.dimensions import *
|
from src.dimensions import *
|
||||||
from src.sprites import *
|
from src.sprites import *
|
||||||
|
from plant import *
|
||||||
|
|
||||||
|
|
||||||
class Tractor(pygame.sprite.Sprite):
|
class Tractor(pygame.sprite.Sprite):
|
||||||
@ -73,10 +72,13 @@ class Tractor(pygame.sprite.Sprite):
|
|||||||
field[self.position[0]][self.position[1]].hydrate()
|
field[self.position[0]][self.position[1]].hydrate()
|
||||||
|
|
||||||
def cut(self, field, pressed_keys):
|
def cut(self, field, pressed_keys):
|
||||||
if pressed_keys[K_c]:
|
field[self.position[0]][self.position[1]].free()
|
||||||
field[self.position[0]][self.position[1]].free()
|
|
||||||
|
|
||||||
def plant(self, field, plant, pressed_keys):
|
def plant(self, plant_map, plants):
|
||||||
if field.planted == 0:
|
print(plant_map[self.position[0]][self.position[1]])
|
||||||
field.planted = plant
|
plant = Plant(self.field[self.position[0]][self.position[1]], plant_map[self.position[0]][self.position[1]])
|
||||||
plant.field = field
|
plants.append(plant)
|
||||||
|
|
||||||
|
def fertilize(self, field, plants, type):
|
||||||
|
if plants[self.position[0]][self.position[1]].species == type:
|
||||||
|
field[self.position[0]][self.position[1]].fertility = 1
|
Loading…
Reference in New Issue
Block a user