-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.py
132 lines (104 loc) · 3.19 KB
/
example.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python3
# example.py
#
# Charles Emerson
# December 13, 2019
#
# Simple visual example to showcase the Dijkstra's algorithm by running
# on a tile map similar to what you might expect from a game
from dijkstra import dijkstra
### INPUT (*** change me ***)
STARTING_ROW = 0
STARTING_COLUMN = 0
CULL_DISTANCE = 100
# A few example tile maps, a tile is positive if it is walkable
# (Top-left is row = zero, column = zero)
# tile_map = [
# [1, 1,],
# [0, 1,],
# ]
# tile_map = [
# [1, 1, 1],
# [0, 1, 0],
# [1, 1, 1]
# ]
tile_map = [
[1, 1, 0, 1, 1, 1],
[1, 1, 0, 1, 0, 1],
[0, 1, 1, 0, 1, 1],
[1, 0, 1, 0, 1, 0],
[0, 1, 1, 1, 1, 1],
]
### SETUP
NUM_COLS = len(tile_map[0])
NUM_ROWS = len(tile_map)
# Construct adjacency list for each walkable tile
adjacency_list = { }
for r in range(NUM_ROWS):
for c in range(NUM_COLS):
index = r * NUM_COLS + c
# Neighboring vertices are keys which map to their distance
vertex_adj_list = {}
# If the tile is non-walkable, ignore it (simple optimization)
if (tile_map[r][c] == 0):
continue
# NORTH
if (r != 0 and tile_map[r-1][c] > 0):
vertex_adj_list[index - NUM_COLS] = 1
# WEST
if (c != 0 and tile_map[r][c-1] > 0):
vertex_adj_list[index - 1] = 1
# SOUTH
if (r != NUM_ROWS - 1 and tile_map[r+1][c] > 0):
vertex_adj_list[index + NUM_COLS] = 1
# EAST
if (c != NUM_COLS - 1 and tile_map[r][c+1] > 0):
vertex_adj_list[index + 1] = 1
# Add to the adjacency list if vertex has at least one neighbor
# (simple optimization)
if (len(vertex_adj_list) != 0):
adjacency_list[index] = vertex_adj_list
# Translate tile map to reuse print_2d_array function
for r in range(NUM_ROWS):
for c in range(NUM_COLS):
if tile_map[r][c] == 0:
tile_map[r][c] = -1
# Helper function for printing 2d array
def print_2d_array(array_2d):
num_rows = len(array_2d)
num_columns = len(array_2d[0])
for r in range(-2, num_rows):
for c in range(-1, num_columns):
if (r == -2 and c != -1):
print(f"{c: >4}", end = "")
elif (r == -1):
print("{0: >4}".format("----"), end = "")
elif (c == -1 and r > -1):
print(f"{r: >3}|", end = "")
print
elif (r > -1 and c > -1 and array_2d[r][c] != -1):
print(f"{array_2d[r][c]: >4}".format(), end = "")
else:
print("{0: >4}".format(""), end = "")
print()
print()
print("TILE MAP (Empty-Space is Non-Walkable)")
print_2d_array(tile_map)
### EXECUTION
print(f"Running Dijkstra's Algorithm from (row = {STARTING_ROW}, column = {STARTING_COLUMN})")
print(f"With a maximum reachable distance of {CULL_DISTANCE - 1}")
print()
source_vertex = STARTING_ROW * NUM_COLS + STARTING_COLUMN
distance_map = dijkstra(adjacency_list, source_vertex, CULL_DISTANCE)
# Overwrites tile_map to all -1 entries
distances = tile_map # Shallow copy
for r in range(NUM_ROWS):
for c in range(NUM_COLS):
distances[r][c] = -1
# Overwrites with the reachable distances
for vertex, distance in distance_map.items():
row = int(vertex / NUM_COLS)
col = vertex % NUM_COLS
distances[row][col] = distance
print("DISTANCE MAP (Empty-Space is Unreachable)")
print_2d_array(distances)