-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexit_compass.py
103 lines (80 loc) · 3.4 KB
/
exit_compass.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
import pickle
from os import path, remove
from typing import Tuple
class ExitCompass():
file_name = "compass.pickle"
def __init__(self):
# for reading also binary mode is important
if path.exists(ExitCompass.file_name):
# loads adjacencies list from pickle
with open(ExitCompass.file_name, 'rb') as f:
self.nav_dict = pickle.load(f)
else:
self.nav_dict = dict()
def clean_compass(self):
if path.exists(ExitCompass.file_name):
remove(ExitCompass.file_name)
self.nav_dict = dict()
def pickle_save(self):
""" saves adjacencies list to pickle """
with open(ExitCompass.file_name, 'wb') as f:
pickle.dump(self.nav_dict, f)
def _comp_path_vec(self, ref: Tuple[int, int],
sample: Tuple[int, int]) -> Tuple[int, int]:
""" vectors substraction """
return (ref[0] - sample[0], ref[1] - sample[1])
def _comp_sum_vec(self, ref: Tuple[int, int],
sample: Tuple[int, int]) -> Tuple[int, int]:
""" vectors sum """
return (ref[0] + sample[0], ref[1] + sample[1])
def calc_vec(self, start: str,
rel_pos: Tuple[int, int]) -> Tuple[int, int]:
""" return nearest exit to player """
if start not in self.nav_dict:
return None
else:
exit_paths = list(
filter(lambda x: x[0][0] == "E", self.nav_dict[start])
)
shortest_path = float("inf")
nearest_exit = None
for i in range(len(exit_paths)):
exit_path = self._comp_path_vec(exit_paths[i][1], rel_pos)
manh_path = exit_path[0] ** 2 + exit_path[1] ** 2
if manh_path < shortest_path:
shortest_path = manh_path
nearest_exit = exit_path
return nearest_exit
def add_ref_vec(self, source: str, dest: str,
ref_vec: Tuple[int, int]) -> None:
""" rebuild the graph """
if source not in self.nav_dict:
self.nav_dict[source] = set()
new_node = (dest, ref_vec)
if source == dest or new_node in self.nav_dict[source]:
return
self.nav_dict[source].add(new_node)
if dest[0][0] == "S":
if dest not in self.nav_dict: # bidirectional dependency
self.nav_dict[dest] = {(dest, (ref_vec[0] * -1,
ref_vec[1] * -1))}
# append data in referenced nodes
references = self.nav_dict[source].copy()
for ref in references:
if ref[0][0] == "S" and ref[0] != dest: # if it's new start
new_ref_vec = self._comp_path_vec(ref_vec, ref[1])
self.nav_dict[ref[0]].add((dest, new_ref_vec))
# append data to dest node from referenced nodes
if dest[0] == "S":
for ref in references:
if ref[0] != dest:
new_ref_vec = self._comp_path_vec(ref[1], ref_vec)
self.nav_dict[dest].add((ref[0], new_ref_vec))
self.pickle_save()
def print_dict(self):
for node in self.nav_dict:
print(f"<{node}>")
for child in self.nav_dict[node]:
print("\t", child)
# compass = ExitCompass()
# print(compass._comp_path_vec((10, -10), (10, -5)))