diff --git a/agent/methods/__pycache__/genetic_algorithm.cpython-311.pyc b/agent/methods/__pycache__/genetic_algorithm.cpython-311.pyc new file mode 100644 index 00000000..e17f1299 Binary files /dev/null and b/agent/methods/__pycache__/genetic_algorithm.cpython-311.pyc differ diff --git a/agent/methods/__pycache__/graph_search.cpython-311.pyc b/agent/methods/__pycache__/graph_search.cpython-311.pyc new file mode 100644 index 00000000..76096b7d Binary files /dev/null and b/agent/methods/__pycache__/graph_search.cpython-311.pyc differ diff --git a/agent/methods/genetic_algorithm.py b/agent/methods/genetic_algorithm.py new file mode 100644 index 00000000..1fe927ef --- /dev/null +++ b/agent/methods/genetic_algorithm.py @@ -0,0 +1,113 @@ +import numpy as np +import random +import math + +def create_initial_population(num_cities, population_size, list): + population = [] + for _ in range(population_size): + chromosome = list.copy() + chromosome.remove((1, 1)) # Usuń punkt (1, 1) z listy + random.shuffle(chromosome) + chromosome.insert(0, (1, 1)) # Dodaj punkt (1, 1) na początku trasy + population.append(chromosome) + return population + +def calculate_distance(city1, city2): + x1, y1 = city1 + x2, y2 = city2 + distance = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) + return distance + +def calculate_fitness(individual): + total_distance = 0 + + num_cities = len(individual) + + for i in range(num_cities - 1): + city1 = individual[i] + city2 = individual[i + 1] + distance = calculate_distance(city1, city2) + total_distance += distance + + fitness = 1 / total_distance + + return fitness + +def crossover(parent1, parent2): + child = [(1, 1)] + [None] * (len(parent1) - 1) # Inicjalizacja dziecka z punktem (1, 1) na początku + start_index = random.randint(1, len(parent1) - 1) + end_index = random.randint(start_index + 1, len(parent1)) + # Skopiuj fragment miast od parent1 do dziecka + child[start_index:end_index] = parent1[start_index:end_index] + # Uzupełnij brakujące miasta z parent2 + remaining_cities = [city for city in parent2 if city not in child] + child[1:start_index] = remaining_cities[:start_index - 1] + child[end_index:] = remaining_cities[start_index - 1:] + return child + +def mutate(individual, mutation_rate): + for i in range(1, len(individual)): # Rozpoczynamy od indeksu 1, aby pominąć punkt (1, 1) + if random.random() < mutation_rate: + j = random.randint(1, len(individual) - 1) # Wybieramy indeks od 1 do ostatniego indeksu + individual[i], individual[j] = individual[j], individual[i] + return individual + +def genetic_algorithm(list): + chromosome_length = 21 + max_generations = 200 + population_size = 200 + crossover_rate = 0.25 + mutation_rate = 0.1 + num_cities = chromosome_length + population = create_initial_population(num_cities, population_size, list) + + best_individual = None + best_fitness = float('-inf') + + for generation in range(max_generations): + # # Oblicz wartości fitness dla każdego osobnika w populacji + # fitness_values = [calculate_fitness(individual) for individual in population] + # population = [x for _, x in sorted(zip(fitness_values, population), reverse=True)] + # fitness_values.sort(reverse=True) + # max_fitness_index = np.argmax(fitness_values) + # # Wybierz najlepszego osobnika z ostatniej populacji + # if fitness_values[max_fitness_index] > best_fitness: + # best_fitness = fitness_values[max_fitness_index] + # best_individual = population[max_fitness_index] + + # # Twórz nową populację z krzyżówek + # new_population = [] + # for _ in range(int(population_size / 2)): + # parent1, parent2 = random.choices(population[:population_size // 2], k=2) + # child1 = crossover(parent1, parent2) + # child2 = crossover(parent2, parent1) + # new_population.extend([child1, child2]) + # # Dokonaj mutacji na nowej populacji + # new_population = [mutate(individual, mutation_rate) for individual in new_population] + # population = new_population + + # Oblicz wartości fitness dla każdego osobnika w populacji + fitness_values = [calculate_fitness(individual) for individual in population] + population = [x for _, x in sorted(zip(fitness_values, population), reverse=True)] + fitness_values.sort(reverse=True) + best_individuals = population[:10] # Wybierz k najlepszych osobników + new_population = best_individuals.copy() + + # Twórz nową populację z krzyżówek i mutacji + while len(new_population) < population_size: + parent1, parent2 = random.choices(best_individuals, k=2) # Wybierz rodziców spośród najlepszych osobników + child = crossover(parent1, parent2) # Krzyżowanie + child = mutate(child, mutation_rate) # Mutacja + new_population.append(child) + + for individual in best_individuals: + fitness = calculate_fitness(individual) + if fitness > best_fitness: + best_fitness = fitness + best_individual = individual + + population = new_population[:population_size] + + + print("Best path:", best_individual) + return best_individual diff --git a/agent/neural_network/__pycache__/inference.cpython-311.pyc b/agent/neural_network/__pycache__/inference.cpython-311.pyc new file mode 100644 index 00000000..2597f796 Binary files /dev/null and b/agent/neural_network/__pycache__/inference.cpython-311.pyc differ diff --git a/agent/neural_network/__pycache__/model.cpython-311.pyc b/agent/neural_network/__pycache__/model.cpython-311.pyc new file mode 100644 index 00000000..fb27ed0f Binary files /dev/null and b/agent/neural_network/__pycache__/model.cpython-311.pyc differ diff --git a/core/chicken/__pycache__/chicken.cpython-311.pyc b/core/chicken/__pycache__/chicken.cpython-311.pyc new file mode 100644 index 00000000..80a06460 Binary files /dev/null and b/core/chicken/__pycache__/chicken.cpython-311.pyc differ diff --git a/core/field/__pycache__/field_block.cpython-311.pyc b/core/field/__pycache__/field_block.cpython-311.pyc new file mode 100644 index 00000000..cdc71fbc Binary files /dev/null and b/core/field/__pycache__/field_block.cpython-311.pyc differ diff --git a/core/field/__pycache__/field_settings.cpython-311.pyc b/core/field/__pycache__/field_settings.cpython-311.pyc new file mode 100644 index 00000000..8510414f Binary files /dev/null and b/core/field/__pycache__/field_settings.cpython-311.pyc differ diff --git a/core/plants/__pycache__/plant.cpython-311.pyc b/core/plants/__pycache__/plant.cpython-311.pyc new file mode 100644 index 00000000..c50f8013 Binary files /dev/null and b/core/plants/__pycache__/plant.cpython-311.pyc differ diff --git a/core/plants/__pycache__/plants_settings.cpython-311.pyc b/core/plants/__pycache__/plants_settings.cpython-311.pyc new file mode 100644 index 00000000..44da7dce Binary files /dev/null and b/core/plants/__pycache__/plants_settings.cpython-311.pyc differ diff --git a/main.py b/main.py index c60b4d59..45fc6a88 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,8 @@ from pygame.locals import * from core.chicken import chicken as chick from core.field import field_settings from core.plants import plants_settings +from agent.methods.genetic_algorithm import genetic_algorithm +import numpy as np from agent.neural_network import inference #import agent.neural_network.inference @@ -71,10 +73,19 @@ class Game: self.search_object = graph_search.Search(self.cell_size, self.cell_number) chicken_next_moves = [] - veggies = dict() veggies_debug = dict() + wheat_list = [obj for obj in self.plant_list if obj.name == "wheat" and obj.state == 0] + + new_list = [()] + a = 1 + for obj in wheat_list: + new_list.append ((obj.xy[0], obj.xy[1])) + + new_list[0] = (1, 1) + best_path = genetic_algorithm(new_list) + while running: clock.tick(60) # manual fps control not to overwork the computer for event in pygame.event.get(): @@ -95,14 +106,21 @@ class Game: if event.type == move_chicken_event: if len(chicken_next_moves) == 0: - angles = {0: 'UP', 90: 'RIGHT', 270: 'LEFT', 180: 'DOWN'} closest_wheat = self.search_object.closest_point(self.chicken.x, self.chicken.y, 'wheat', self.plant_list) - self.aim_list[0].xy[0] = closest_wheat[0] - self.aim_list[0].xy[1] = closest_wheat[1] - chicken_next_moves = self.search_object.astarsearch( - [self.chicken.x, self.chicken.y, angles[self.chicken.angle]], [closest_wheat[0], closest_wheat[1]], self.stone_list, self.plant_list) + # self.aim_list[0].xy[0] = closest_wheat[0] + # self.aim_list[0].xy[1] = closest_wheat[1] + self.aim_list[0].xy[0] = best_path[a][0] + self.aim_list[0].xy[1] = best_path[a][1] + # a += 1 + # target = wheat_list[a] + # chicken_next_moves = self.search_object.astarsearch( + # [self.chicken.x, self.chicken.y, angles[self.chicken.angle]], [closest_wheat[0], closest_wheat[1]], self.stone_list, self.plant_list) + chicken_next_moves = self.search_object.astarsearch( + [self.chicken.x, self.chicken.y, angles[self.chicken.angle]], [best_path[a][0], best_path[a][1]], self.stone_list, self.plant_list) + + a += 1 #neural_network current_veggie = next(os.walk('./agent/neural_network/images/test'))[1][random.randint(0, len(next(os.walk('./agent/neural_network/images/test'))[1])-1)] if(current_veggie in veggies_debug):