Added first (still a tad ugly) draft of pathfinding. Added some small bits of documentation. Started working on unit tests (planettest.py).
This commit is contained in:
parent
631d70aacc
commit
57d731409f
2 changed files with 66 additions and 6 deletions
|
@ -25,12 +25,24 @@ Weight = int
|
||||||
|
|
||||||
'''
|
'''
|
||||||
https://www.python.org/dev/peps/pep-0289/
|
https://www.python.org/dev/peps/pep-0289/
|
||||||
Node checking:
|
Node checking examples:
|
||||||
((0,0),Direction.NORTH) in planetmap[0]
|
((0,0),Direction.NORTH) in planetmap[0]
|
||||||
Simplify this for node search:
|
Simplify this for node search:
|
||||||
next(x for (x, y), direction in planetmap[0])
|
next(x for (x, y), direction in planetmap[0])
|
||||||
next(y for x, y in planetmap[0] if x == (0, 0))
|
next(y for x, y in planetmap[0] if x == (0, 0))
|
||||||
planetmap[0][next((x, y) for x, y in planetmap[0] if y == 'North')]
|
planetmap[0][next((x, y) for x, y in planetmap[0] if y == 'North')]
|
||||||
|
|
||||||
|
formatting example of bidirectional map:
|
||||||
|
{
|
||||||
|
(0, 0): {
|
||||||
|
<Direction.EAST: 90>: ((0, 0), <Direction.WEST: 270>, 1),
|
||||||
|
<Direction.WEST: 270>: ((0, 0), <Direction.EAST: 90>, 1),
|
||||||
|
<Direction.NORTH: 0>: ((0, 1), <Direction.SOUTH: 180>, 2)
|
||||||
|
},
|
||||||
|
(0, 1): {
|
||||||
|
<Direction.SOUTH: 180>: ((0, 0), <Direction.NORTH: 0>, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
#Contains the representation of the map and provides certain functions to manipulate it according to the specifications
|
#Contains the representation of the map and provides certain functions to manipulate it according to the specifications
|
||||||
|
@ -40,7 +52,7 @@ class Planet:
|
||||||
self._planetmap = {}
|
self._planetmap = {}
|
||||||
self.target = None
|
self.target = None
|
||||||
|
|
||||||
#Adds a bidirectional path defined between the start and end coordinates to the map and assigns the weight to it.
|
# Adds a bidirectional path defined between the start and end coordinates to the map and assigns the weight to it.
|
||||||
def add_path(self, start: Tuple[Tuple[int, int], Direction], target: Tuple[Tuple[int, int], Direction], weight: int):
|
def add_path(self, start: Tuple[Tuple[int, int], Direction], target: Tuple[Tuple[int, int], Direction], weight: int):
|
||||||
if(start[0] not in self._planetmap):
|
if(start[0] not in self._planetmap):
|
||||||
self._planetmap[start[0]] = {}
|
self._planetmap[start[0]] = {}
|
||||||
|
@ -54,6 +66,32 @@ class Planet:
|
||||||
def get_paths(self) -> Dict[Tuple[int, int], Dict[Direction, Tuple[Tuple[int, int], Direction, Weight]]]:
|
def get_paths(self) -> Dict[Tuple[int, int], Dict[Direction, Tuple[Tuple[int, int], Direction, Weight]]]:
|
||||||
return self._planetmap
|
return self._planetmap
|
||||||
|
|
||||||
#Returns a shortest path between two nodes
|
'''
|
||||||
|
Returns a shortest path between two nodes.
|
||||||
|
Used Algorithm: Dijkstra's Algorithm, will be "replaced" by A* later
|
||||||
|
Formatting:
|
||||||
|
List = [(total_len, (current_node, [((node), Direction)]))]
|
||||||
|
'''
|
||||||
def shortest_path(self, start: Tuple[int, int], target: Tuple[int, int]) -> Optional[List[Tuple[Tuple[int, int], Direction]]]:
|
def shortest_path(self, start: Tuple[int, int], target: Tuple[int, int]) -> Optional[List[Tuple[Tuple[int, int], Direction]]]:
|
||||||
pass
|
if((start in self._planetmap) and (target in self._planetmap)):
|
||||||
|
self.path_found = []
|
||||||
|
self.path_search = [(0, (start, []))]
|
||||||
|
while True:
|
||||||
|
for srcdir, (destnode, destdir, weight) in self._planetmap[self.path_search[0][1][0]].items():
|
||||||
|
if(destnode not in self.path_found and weight > 0): # check if in shortest_found
|
||||||
|
for x, (s_node, s_pathlist) in self.path_search:
|
||||||
|
if (destnode == s_node and self.path_search[0][0] + weight < x):
|
||||||
|
self.path_search.remove((x, (s_node, s_pathlist)))
|
||||||
|
if(s_weight for s_weight, (s_node, s_pathlist) in self.path_search if s_node == destnode):
|
||||||
|
self.path_search.append((self.path_search[0][0]+weight, (destnode, self.path_search[0][1][1] + [(self.path_search[0][1][0], srcdir)])))
|
||||||
|
self.path_found.append(self.path_search[0][1][0])
|
||||||
|
self.path_search.pop(0)
|
||||||
|
if(self.path_search == []): # if map is empty
|
||||||
|
break
|
||||||
|
self.path_search.sort()
|
||||||
|
if(self.path_search[0][1][0] == target):
|
||||||
|
return self.path_search[0][1][1]
|
||||||
|
else:
|
||||||
|
print("Destination is not reachable from start.")
|
||||||
|
else:
|
||||||
|
print("Cannot calculate shortest Path. Start or target is not in known.")
|
||||||
|
|
|
@ -45,17 +45,39 @@ class YourFirstTestPlanet(unittest.TestCase):
|
||||||
|
|
||||||
MODEL YOUR TEST PLANET HERE (if you'd like):
|
MODEL YOUR TEST PLANET HERE (if you'd like):
|
||||||
|
|
||||||
|
(_target)
|
||||||
|
+-0,3-----2,3 +---+
|
||||||
|
| | | | |
|
||||||
|
| 0,2-----2,2-3,2 |
|
||||||
|
| | / | |
|
||||||
|
| 0,1 / +---+
|
||||||
|
| | /
|
||||||
|
+-0,0-1,0-----3.0-4.0
|
||||||
|
|
|
||||||
|
(start)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# set your data structure
|
# set your data structure
|
||||||
self.planet = Planet()
|
self.planet = Planet()
|
||||||
|
|
||||||
# ADD YOUR PATHS HERE:
|
# ADD YOUR PATHS HERE:
|
||||||
# self.planet.add_path(...)
|
self.planet.add_path(((0, 0), Direction.NORTH), ((0, 1), Direction.SOUTH), 1)
|
||||||
|
self.planet.add_path(((0, 0), Direction.EAST), ((1, 0), Direction.WEST), 1)
|
||||||
|
self.planet.add_path(((0, 0), Direction.WEST), ((0, 3), Direction.WEST), 2)
|
||||||
|
self.planet.add_path(((0, 1), Direction.NORTH), ((0, 2), Direction.SOUTH), 1)
|
||||||
|
self.planet.add_path(((0, 2), Direction.NORTH), ((0, 3), Direction.SOUTH), 1)
|
||||||
|
self.planet.add_path(((0, 2), Direction.EAST), ((2, 2), Direction.WEST), 2)
|
||||||
|
self.planet.add_path(((0, 3), Direction.EAST), ((2, 3), Direction.WEST), -1)
|
||||||
|
self.planet.add_path(((1, 0), Direction.NORTH), ((2, 2), Direction.SOUTH), 2)
|
||||||
|
self.planet.add_path(((1, 0), Direction.EAST), ((3, 0), Direction.WEST), 1)
|
||||||
|
self.planet.add_path(((2, 2), Direction.NORTH), ((2, 3), Direction.SOUTH), 3)
|
||||||
|
self.planet.add_path(((3, 0), Direction.EAST), ((4, 0), Direction.WEST), -1)
|
||||||
|
self.planet.add_path(((3, 2), Direction.NORTH), ((3, 2), Direction.SOUTH), 1)
|
||||||
|
|
||||||
def test_integrity(self):
|
def test_integrity(self):
|
||||||
# were all paths added correctly to the planet
|
# were all paths added correctly to the planet
|
||||||
# check if add_path() works by using get_paths()
|
# check if add_path() works by using get_paths()
|
||||||
self.fail('implement me!')
|
self.planet.get_paths()
|
||||||
|
|
||||||
def test_empty_planet(self):
|
def test_empty_planet(self):
|
||||||
self.fail('implement me!')
|
self.fail('implement me!')
|
||||||
|
|
Loading…
Reference in a new issue