def find_shortest_path(grid, start_node, end_node):
marked_grid = [[None for i in range(len(j))] for j in grid]
step = 0
current_wave = [start_node]
manhattan_distance = ((-1, 0), (1, 0), (0, -1), (0, 1))
def generate_new_wave(current, new_wave):
possible_steps = list(filter(lambda x: -1 not in x and len(marked_grid) not in x
and marked_grid[x[0]][x[1]] is None
and x not in new_wave,
[tuple(map(lambda x, y: x + y, current, n)) for n in manhattan_distance]))
for step in possible_steps:
yield step
def build_new_wave():
new_wave = []
for current in current_wave:
marked_grid[current[0]][current[1]] = step
for drop in generate_new_wave(current, new_wave):
new_wave.append(drop)
return new_wave
while marked_grid[end_node[0]][end_node[1]] is None:
if len(current_wave) == 0:
step += 1
return False
current_wave = build_new_wave()
step += 1
recovered_path = []
step -= 1
while step != 0:
recovered_path.append(end_node)
for n in manhattan_distance:
candidate = tuple(map(lambda x, y: x + y, end_node, n))
try:
if marked_grid[candidate[0]][candidate[1]] == step - 1:
end_node = candidate
step -= 1
break
except IndexError:
pass
return list(reversed(recovered_path + [start_node]))
grid = [[(0,0), (0,1), (0,2), (0,3), (0,4)],
[(1,0), (1,1), (1,2), (1,3), (1,4)],
[(2,0), (2,1), (2,2), (2,3), (2,4)],
[(3,0), (3,1), (3,2), (3,3), (3,4)],
[(4,0), (4,1), (4,2), (4,3), (4,4)]
]
start_node = (0, 0)
end_node = (4, 4)
print(find_shortest_path(grid, start_node, end_node))