import random as rand from pathlib import Path def generate_grid(height: int, width: int, fill_percent: int = 70): """ Generates grid with a simple maze. Path is signed as 'p' and walls as 'w'. It always has walls surrounding it. :param height: height of the grid. :param width: width of the grid. :param fill_percent: percentage of walls in the maze (not counting surrounding walls). :return: """ grid = [] for i in range(height): grid.append([]) for j in range(width): grid[i].append('w') path_percent = (100. - float(fill_percent)) / 100. grid_size = float((height-2) * (width-2)) paths_number = int(path_percent * grid_size) start_point_y = height // 2 start_point_x = width // 2 grid[start_point_y][start_point_x] = 'p' set_paths = 1 path_list = [(start_point_y, start_point_x)] while set_paths < paths_number: chosen_position = rand.randint(0, len(path_list)-1) random_growth = rand.randint(0, 3) if random_growth == 0: if path_list[chosen_position][0]+1 == height-1: continue else: new_y = path_list[chosen_position][0] + 1 new_x = path_list[chosen_position][1] if grid[new_y][new_x] == 'w': if grid[new_y][new_x-1] == 'p' or grid[new_y][new_x+1] == 'p' or grid[new_y+1][new_x] == 'p': if rand.randint(0, 100) < 1: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) else: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) elif random_growth == 1: if path_list[chosen_position][1]-1 == 0: continue else: new_y = path_list[chosen_position][0] new_x = path_list[chosen_position][1] - 1 if grid[new_y][new_x] == 'w': if grid[new_y][new_x-1] == 'p' or grid[new_y-1][new_x] == 'p' or grid[new_y+1][new_x] == 'p': if rand.randint(0, 100) < 1: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) else: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) elif random_growth == 2: if path_list[chosen_position][0]-1 == 0: continue else: new_y = path_list[chosen_position][0]-1 new_x = path_list[chosen_position][1] if grid[new_y][new_x] == 'w': if grid[new_y][new_x+1] == 'p' or grid[new_y][new_x-1] == 'p' or grid[new_y-1][new_x] == 'p': if rand.randint(0, 100) < 1: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) else: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) elif random_growth == 3: if path_list[chosen_position][1] + 1 == width-1: continue else: new_y = path_list[chosen_position][0] new_x = path_list[chosen_position][1] + 1 if grid[new_y][new_x] == 'w': if grid[new_y][new_x+1] == 'p' or grid[new_y-1][new_x] == 'p' or grid[new_y+1][new_x] == 'p': if rand.randint(0, 100) < 1: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) else: grid[new_y][new_x] = 'p' set_paths += 1 path_list.append((new_y, new_x)) return grid def write_grid_as_graph_to_file(grid, filename, path="grids/"): """ Writes generated grid to file as a graph with weights :param grid: grid generated by function generate_grid :param filename: name of the file to save the graph to :param path: path to save the file in :return: None """ with open(path + filename, 'w') as file: for i in range(1, len(grid)-1): for j in range(1, len(grid[i])-1): if grid[i][j] == 'p': if grid[i-1][j] == 'p': file.write(str(i) + " " + str(j) + "," + str(i-1) + " " + str(j) + "," + "1" + "\n") if grid[i+1][j] == 'p': file.write(str(i) + " " + str(j) + "," + str(i+1) + " " + str(j) + "," + "1" + "\n") if grid[i][j-1] == 'p': file.write(str(i) + " " + str(j) + "," + str(i) + " " + str(j-1) + "," + "1" + "\n") if grid[i][j+1] == 'p': file.write(str(i) + " " + str(j) + "," + str(i) + " " + str(j+1) + "," + "1" + "\n") def read_grid_graph_from_file(filename, path="grids/"): N = set() A = {} A_b = {} w = {} with open(path + filename, "r") as file: line = file.readline() while line != '': split = line.strip("\n").split(",") fist_node_str_list = split[0].split(" ") second_node_str_list = split[1].split(" ") weight = int(split[2]) first_node = (int(fist_node_str_list[0]), int(fist_node_str_list[1])) second_node = (int(second_node_str_list[0]), int(second_node_str_list[1])) N.add(first_node) N.add(second_node) if first_node not in A.keys(): A[first_node] = [second_node] else: A[first_node].append(second_node) if second_node not in A_b.keys(): A_b[second_node] = [first_node] else: A_b[second_node].append(first_node) w[(first_node, second_node)] = weight line = file.readline() return N, A, A_b, w if __name__ == "__main__": n = [(20, 20), (50, 50), (100, 100), (150, 150), (250, 250), (500, 500)] for i in range(1, len(n)+1): p = "grids/" + str(n[i-1][0]) + "x" + str(n[i-1][1]) + "/" print("generating graphs group:", n[i - 1]) for j in range(1, 51): f = "grid" + str(j) print(f) g = generate_grid(n[i-1][0]+2, n[i-1][1]+2) Path(p).mkdir(parents=True, exist_ok=True) write_grid_as_graph_to_file(g, f, p) print()