163 lines
6.4 KiB
Python
163 lines
6.4 KiB
Python
|
import random as rand
|
||
|
|
||
|
|
||
|
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__":
|
||
|
for i in range(1, 11):
|
||
|
print("generating graph:", i, "of", 10)
|
||
|
f = "grid" + str(i)
|
||
|
g = generate_grid(rand.randint(202, 502), rand.randint(202, 502))
|
||
|
write_grid_as_graph_to_file(g, f)
|