import random from copy import copy import settings import tree def evaluate_values(fuel, water, feritizer, seeds, fields_with_plants, k): fields_to_sow = 0 fields_to_water = 0 fields_to_feritize = 0 fields_to_harvest = 0 width = settings.Field.horizontal_count() height = settings.Field.vertical_count() ans = 0 for i in range(width): for j in range(height): if fields_with_plants[i][j] == 'potato_empty' or fields_with_plants[i][j] == 'carrot_empty' or \ fields_with_plants[i][j] == 'wheat_empty': fields_to_sow += 1 elif fields_with_plants[i][j] == 'potato_sow' or fields_with_plants[i][j] == 'carrot_sow' or \ fields_with_plants[i][j] == 'wheat_sow': fields_to_water += 1 elif fields_with_plants[i][j] == 'potato_watered' or fields_with_plants[i][j] == 'carrot_watered' or \ fields_with_plants[i][j] == 'wheat_watered': fields_to_feritize += 1 elif fields_with_plants[i][j] == 'potato_feritized' or fields_with_plants[i][j] == 'carrot_feritized' or \ fields_with_plants[i][j] == 'wheat_feritized': fields_to_harvest += 1 t = tree.treelearn() if water < fields_to_water or feritizer < fields_to_feritize or seeds < fields_to_sow or fuel < 1000: return 5 if tree.make_decision(t, fuel, water, feritizer, 0, 0, 0, 0, 0, seeds): return 5 if fuel > 2000: return 0 if k == 0: ans += (fuel) / 30 - fields_to_harvest ans += water - fields_to_water ans += feritizer - fields_to_feritize - fields_to_water ans += seeds - fields_to_harvest - fields_to_sow fuel = fuel - 1500 water = water - fields_to_water feritizer = feritizer - fields_to_feritize - fields_to_water seeds = seeds - fields_to_harvest - fields_to_sow if water < 0: return 10 if feritizer < 0: return 10 if seeds < 0: return 10 if fuel < 0: return 10 if k == 1: ans += water - fields_to_water ans += feritizer - fields_to_water - fields_to_feritize ans += seeds - fields_to_sow ans += (fuel - 1100) / 30 - fields_to_harvest fuel = fuel - 1500 water = water - fields_to_water feritizer = feritizer - fields_to_water - fields_to_feritize seeds = seeds - fields_to_sow if water < 0: return 10 if feritizer < 0: return 10 if seeds < 0: return 10 if fuel < 0: return 10 if k == 2: ans += feritizer - fields_to_feritize ans += seeds - fields_to_sow ans += (fuel - 800) / 15 - fields_to_feritize - fields_to_harvest ans += water - fields_to_water - fields_to_sow feritizer = feritizer - fields_to_feritize seeds = seeds - fields_to_sow fuel -= 1500 water = water - fields_to_water - fields_to_sow if water < 0: return 10 if feritizer < 0: return 10 if seeds < 0: return 10 if fuel < 0: return 10 if k == 3: ans += seeds - fields_to_sow ans += (fuel - 400) / 30 - fields_to_harvest ans += water - fields_to_water - fields_to_sow ans += feritizer - fields_to_feritize - fields_to_water - fields_to_sow fuel -= 1500 seeds = seeds - fields_to_sow water = water - fields_to_water - fields_to_sow feritizer = feritizer - fields_to_feritize - fields_to_water - fields_to_sow if water < 0: return 10 if feritizer < 0: return 10 if seeds < 0: return 10 if fuel < 0: return 10 if tree.make_decision(t, fuel, water, feritizer, 15, 15, 15, 10, 10, seeds): return 15 if k == 0: fuel = fuel-500 if tree.make_decision(t, fuel, water, feritizer, 15, 15, 15, 10, 10, seeds): return ans else: ans += 50 water = water - fields_to_harvest - fields_to_sow-10 if k == 1: water = water - fields_to_harvest - fields_to_sow-10 if tree.make_decision(t, fuel - 400, water, feritizer, 15, 15, 15, 10, 10, seeds): return ans else: ans += 50 if k == 2: feritizer = feritizer - fields_to_sow - fields_to_water-10 if tree.make_decision(t, fuel - 400, water, feritizer, 15, 15, 15, 10, 10, seeds): return ans else: ans += 50 if k == 3: seeds = seeds - fields_to_water - fields_to_feritize-10 if tree.make_decision(t, fuel - 400, water, feritizer, 15, 15, 15, 10, 10, seeds): return ans else: ans += 50 return ans def fitness(solution, fields_plants, k): fuel = solution[0] water = solution[1] feritizer = solution[2] seeds = solution[3] if fuel / 30 + water + feritizer + seeds > 200: ans = 0 else: ans = evaluate_values(fuel, water, feritizer, seeds, fields_plants, k) return ans def solution(fields_with_plants, l): solutions = [] ranked_solutions = [] for i in range(10000): solution = [] fuel = random.randint(0, 2000) water = random.randint(0, 100) feritizer = random.randint(0, 100) seeds = random.randint(0, 100) solution.append(fuel) solution.append(water) solution.append(feritizer) solution.append(seeds) solutions.append(solution) for s in solutions: ranked_solutions.append((fitness(s, fields_with_plants, l), s)) ranked_solutions.sort() ranked_solutions.reverse() best_solutions = ranked_solutions[:100] k = 1 print("Gen 1 best solution: " + str(ranked_solutions[0])) for q in range(4): k += 1 random_cross = random.randint(0, 3) random_mutation_place = random.randint(0, 3) random_mutation = random.randint(1, 5) ranked_solutions = [] solutions = [] solutions.append(best_solutions[0][1]) for i in range(100): for j in range(100): if i == j: continue random_mutation_chance = random.randint(1, 100) solution = copy(best_solutions[i][1]) solution[random_cross:4] = best_solutions[j][1][random_cross:4] if random_mutation_chance <= 3: if random_mutation_place == 0: solution[random_mutation_place] = solution[random_mutation_place] + random_mutation * 30 else: solution[random_mutation_place] = solution[random_mutation_place] + random_mutation solutions.append(copy(solution)) for s in solutions: ranked_solutions.append((fitness(s, fields_with_plants, l), s)) ranked_solutions.sort() ranked_solutions.reverse() best_solutions = ranked_solutions[:100] print("Gen " + str(k) + " best solution: " + str(ranked_solutions[0])) return ranked_solutions[0][1][0], ranked_solutions[0][1][1], ranked_solutions[0][1][2], ranked_solutions[0][1][3]