def evaluate_to_sun( individual: (Node, List[Node]), pop_coord, block_buffer: BlockBuffer): root = individual[0] # Place the sun sun_coordinate = (pop_coord[0] - 10, pop_coord[1] + 10, pop_coord[2] - 10) block_buffer.add_block(sun_coordinate, 0, GOLD_BLOCK) block_buffer.send_to_server() blocks = block_buffer.get_cube_info( pop_coord, (sun_coordinate[0] - 1, sun_coordinate[1] + 1, sun_coordinate[2] - 1)) _sun = [b for b in blocks if b.type == GOLD_BLOCK] assert len(_sun) == 1, "no sun found" _sun = _sun[0] closest_to_sun = float("inf") for b in blocks: if b.type != AIR and b.type != GOLD_BLOCK: dist = (b.position.x - _sun.position.x) ** 2 + \ (b.position.y - _sun.position.y) ** 2 + \ (b.position.z - _sun.position.z) ** 2 dist = dist**0.5 if dist < closest_to_sun: closest_to_sun = dist return closest_to_sun
def scratch(): # n = Node(0, 1, start_coord) bb = BlockBuffer() # set_nodes_as_blocks(n, start_coord, bb) # bb.send_to_server() end_coord = (start_coord[0], start_coord[1] + 100, start_coord[2] - 100) blocks = bb.get_cube_info(start_coord, end_coord)
def set_nodes_as_blocks(node: Node, coordinate: (int, int, int), block_buffer: BlockBuffer, block_type=None): block_type = block_type if block_type is not None else node.block_type block_orientation = node.orientation block_buffer.add_block(coordinate, block_orientation, block_type) for side_idx, neigh in enumerate(node.neighbors): if neigh is not None: set_nodes_as_blocks(neigh, move_coordinate(coordinate, side_idx), block_buffer)
def evolution(gens=1000, pop_num=200, mutation_p=0.1, parent_cut_r=0.1): population_coordinates = [(start_coord[0], start_coord[1], start_coord[2] + (i * 20)) for i in range(pop_num)] population = [generate_individual(c) for c in population_coordinates] block_buffer = BlockBuffer() for generation in range(gens): if generation == 0 or generation == 1: time.sleep(50) # Clear the area client.fillCube( FillCubeRequest(cube=Cube(min=Point(x=slots_start[0], y=slots_start[1], z=slots_start[2]), max=Point(x=slots_end[0], y=slots_end[1], z=slots_end[2])), type=AIR)) # Show population client.spawnBlocks(Blocks([ind.get_blocks() for ind in population])) print(f"Generation --> {generation}") get_ind_blocks = lambda i: client.readCube(min=i.get_slot_min(), max=i.get_slot_max()) population_blocks = list(map(evaluate, population)) evaluations = map(evaluate, population_blocks) pop_eval_zipped = zip(population, evaluations) pop_eval_zipped = \ sorted(pop_eval_zipped, key=itemgetter(1), reverse=False) sorted_population, _ = map(list, zip(*pop_eval_zipped)) parent_cuttoff_idx = int(parent_cut_r * pop_num) parents = sorted_population[:parent_cuttoff_idx] next_generation = [clone_individual(parents[0])] for _ in range(pop_num - 1): p1 = parents[randint(0, len(parents))] p2 = parents[randint(0, len(parents))] c = crossover(p1, p2) if uniform(0, 1) < mutation_p: c = mutation(c[0]) next_generation.append(c) population = next_generation
def evolution(generations=1000, pop_number=200, mutation_prob=0.1, parent_cuttoff_ratio=0.1): population_coordinates = [(start_coord[0], start_coord[1], start_coord[2] + (i * 20)) for i in range(pop_number)] population = [generate_individual(c) for c in population_coordinates] block_buffer = BlockBuffer() for generation in range(generations): if generation == 0 or generation == 1: time.sleep(50) delete_patch(block_buffer) show_population(population, population_coordinates, block_buffer) print(f"Generation --> {generation}") evaluate_ = lambda ind_coord: evaluate_to_sun(ind_coord[0], ind_coord[ 1], block_buffer) evaluations = list( map(evaluate_, zip(population, population_coordinates))) print(min(evaluations)) pop_eval_zipped = zip(population, evaluations) pop_eval_zipped = sorted(pop_eval_zipped, key=itemgetter(1), reverse=False) sorted_population, _ = map(list, zip(*pop_eval_zipped)) parent_cuttoff_idx = int(parent_cuttoff_ratio * pop_number) parents = sorted_population[:parent_cuttoff_idx] next_generation = [clone_individual(parents[0])] for _ in range(pop_number - 1): p1 = parents[randint(0, len(parents))] p2 = parents[randint(0, len(parents))] c = crossover(p1, p2) if uniform(0, 1) < mutation_prob: c = mutation(c[0]) next_generation.append(c) population = next_generation
def show_population(population, coordinates, block_buffer: BlockBuffer): root_nodes_pop = list(zip(*population)) roots_and_coordinates = zip(root_nodes_pop[0], coordinates) buffer_blocks_fn = lambda r: set_nodes_as_blocks(r[0], r[1], block_buffer) list(map(buffer_blocks_fn, roots_and_coordinates)) block_buffer.send_to_server()