Map-tested diagonals and crossover links
This commit is contained in:
parent
30fe0c4b5f
commit
ea63071c64
2 changed files with 174 additions and 10 deletions
|
|
@ -76,7 +76,7 @@ See `./example_maps.py` for some empty grid areas to start from.
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from scipy.sparse.csgraph import dijkstra
|
from scipy.sparse.csgraph import dijkstra, breadth_first_order
|
||||||
from scipy.sparse import csr_matrix
|
from scipy.sparse import csr_matrix
|
||||||
from scipy import zeros
|
from scipy import zeros
|
||||||
except ImportError as err:
|
except ImportError as err:
|
||||||
|
|
@ -105,7 +105,7 @@ _MAPSCAN = {
|
||||||
"s": (0, -1),
|
"s": (0, -1),
|
||||||
"sw": (-1, -1),
|
"sw": (-1, -1),
|
||||||
"w": (-1, 0),
|
"w": (-1, 0),
|
||||||
"nw": (1, -1)
|
"nw": (-1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
_BIG = 999999999999
|
_BIG = 999999999999
|
||||||
|
|
@ -392,6 +392,9 @@ class MapLink:
|
||||||
# from evennia import set_trace;set_trace()
|
# from evennia import set_trace;set_trace()
|
||||||
end_direction = self.get_directions(start_direction, xygrid).get(start_direction)
|
end_direction = self.get_directions(start_direction, xygrid).get(start_direction)
|
||||||
if not end_direction:
|
if not end_direction:
|
||||||
|
if _steps is None:
|
||||||
|
# is perfectly okay to not be linking to a node
|
||||||
|
return None, 0, None
|
||||||
raise MapParserError(f"Link at ({self.x}, {self.y}) was connected to "
|
raise MapParserError(f"Link at ({self.x}, {self.y}) was connected to "
|
||||||
f"from {start_direction}, but does not link that way.")
|
f"from {start_direction}, but does not link that way.")
|
||||||
|
|
||||||
|
|
@ -884,6 +887,10 @@ class Map:
|
||||||
startnode = self.get_node_from_coord(startcoord)
|
startnode = self.get_node_from_coord(startcoord)
|
||||||
endnode = self.get_node_from_coord(endcoord)
|
endnode = self.get_node_from_coord(endcoord)
|
||||||
|
|
||||||
|
if not endnode:
|
||||||
|
# no node at given coordinate. No path is possible.
|
||||||
|
return [], []
|
||||||
|
|
||||||
if self.pathfinding_routes is None:
|
if self.pathfinding_routes is None:
|
||||||
self._calculate_path_matrix()
|
self._calculate_path_matrix()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,86 @@ MAP2_DISPLAY = """
|
||||||
#-#-#-#
|
#-#-#-#
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
|
MAP4 = r"""
|
||||||
|
|
||||||
|
+ 0 1
|
||||||
|
|
||||||
|
1 #-#
|
||||||
|
|\|
|
||||||
|
0 #-#
|
||||||
|
|
||||||
|
+ 0 1
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAP4 = r"""
|
||||||
|
|
||||||
|
+ 0 1 2 3 4 5
|
||||||
|
|
||||||
|
5 #-#---# #
|
||||||
|
| / \ /
|
||||||
|
4 # / #
|
||||||
|
|/ |
|
||||||
|
3 # #
|
||||||
|
|\ / \
|
||||||
|
2 # #-# #
|
||||||
|
|/ \ /
|
||||||
|
1 # #
|
||||||
|
/ \ |
|
||||||
|
0 # #---#-#
|
||||||
|
|
||||||
|
+ 0 1 2 3 4 5
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAP4_DISPLAY = r"""
|
||||||
|
#-#---# #
|
||||||
|
| / \ /
|
||||||
|
# / #
|
||||||
|
|/ |
|
||||||
|
# #
|
||||||
|
|\ / \
|
||||||
|
# #-# #
|
||||||
|
|/ \ /
|
||||||
|
# #
|
||||||
|
/ \ |
|
||||||
|
# #---#-#
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
MAP5 = r"""
|
||||||
|
|
||||||
|
+ 0 1 2 3 4
|
||||||
|
|
||||||
|
4 #-# #---#
|
||||||
|
x /
|
||||||
|
3 #-#-#
|
||||||
|
|x x|
|
||||||
|
2 #-#-#-#
|
||||||
|
| | |
|
||||||
|
1 #-+-#-+-#
|
||||||
|
| |
|
||||||
|
0 #---#
|
||||||
|
|
||||||
|
+ 0 1 2 3 4
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAP5_DISPLAY = r"""
|
||||||
|
#-# #---#
|
||||||
|
x /
|
||||||
|
#-#-#
|
||||||
|
|x x|
|
||||||
|
#-#-#-#
|
||||||
|
| | |
|
||||||
|
#-+-#-+-#
|
||||||
|
| |
|
||||||
|
#---#
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
|
||||||
class TestMap1(TestCase):
|
class TestMap1(TestCase):
|
||||||
"""
|
"""
|
||||||
Test the Map class with a simple map and default symbol legend.
|
Test the Map class with a simple 4-node map
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -131,23 +207,24 @@ class TestMap1(TestCase):
|
||||||
self.assertEqual(expectlst, maplst[::-1]) # flip y-axis to match print direction
|
self.assertEqual(expectlst, maplst[::-1]) # flip y-axis to match print direction
|
||||||
|
|
||||||
@parameterized.expand([
|
@parameterized.expand([
|
||||||
((0, 0), '# \n| \n@-#'),
|
((0, 0), 1, '# \n| \n@-#'),
|
||||||
((0, 1), '@-#\n| \n# '),
|
((0, 1), 1, '@-#\n| \n# '),
|
||||||
((1, 0), ' #\n |\n#-@'),
|
((1, 0), 1, ' #\n |\n#-@'),
|
||||||
((1, 1), '#-@\n |\n #'),
|
((1, 1), 1, '#-@\n |\n #'),
|
||||||
|
((0, 0), 2, ''),
|
||||||
|
|
||||||
])
|
])
|
||||||
def test_get_map_display__nodes__character(self, coord, expected):
|
def test_get_map_display__nodes__character(self, coord, dist, expected):
|
||||||
"""
|
"""
|
||||||
Get sub-part of map with node-mode.
|
Get sub-part of map with node-mode.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
mapstr = self.map.get_map_display(coord, dist=1, mode='nodes', character='@')
|
mapstr = self.map.get_map_display(coord, dist=dist, mode='nodes', character='@')
|
||||||
self.assertEqual(expected, mapstr)
|
self.assertEqual(expected, mapstr)
|
||||||
|
|
||||||
class TestMap2(TestCase):
|
class TestMap2(TestCase):
|
||||||
"""
|
"""
|
||||||
Test with Map2 - a bigger map with some links crossing nodes.
|
Test with Map2 - a bigger map with multi-step links
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
@ -251,3 +328,83 @@ class TestMap2(TestCase):
|
||||||
mapstr = self.map.get_map_display(coord, dist=dist, mode='nodes', character='@',
|
mapstr = self.map.get_map_display(coord, dist=dist, mode='nodes', character='@',
|
||||||
max_size=max_size)
|
max_size=max_size)
|
||||||
self.assertEqual(expected, mapstr)
|
self.assertEqual(expected, mapstr)
|
||||||
|
|
||||||
|
|
||||||
|
class TestMap4(TestCase):
|
||||||
|
"""
|
||||||
|
Test Map4 - Map with diaginal links
|
||||||
|
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
self.map = mapsystem.Map({"map": MAP4})
|
||||||
|
|
||||||
|
def test_str_output(self):
|
||||||
|
"""Check the display_map"""
|
||||||
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split('\n'))
|
||||||
|
self.assertEqual(MAP4_DISPLAY, stripped_map)
|
||||||
|
|
||||||
|
@parameterized.expand([
|
||||||
|
((0, 0), (1, 0), ()), # no node at (1, 0)!
|
||||||
|
((2, 0), (5, 0), ('e', 'e')), # straight path
|
||||||
|
((0, 0), (1, 1), ('ne', )),
|
||||||
|
((4, 1), (4, 3), ('nw', 'ne')),
|
||||||
|
((4, 1), (4, 3), ('nw', 'ne')),
|
||||||
|
((2, 2), (3, 5), ('nw', 'ne')),
|
||||||
|
((2, 2), (1, 5), ('nw', 'n', 'n')),
|
||||||
|
((5, 5), (0, 0), ('sw', 's', 'sw', 'w', 'sw', 'sw')),
|
||||||
|
((5, 5), (0, 0), ('sw', 's', 'sw', 'w', 'sw', 'sw')),
|
||||||
|
((5, 2), (1, 2), ('sw', 'nw', 'w', 'nw', 's')),
|
||||||
|
((4, 1), (1, 1), ('s', 'w', 'nw'))
|
||||||
|
])
|
||||||
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
||||||
|
"""
|
||||||
|
Test shortest-path calculations throughout the grid.
|
||||||
|
|
||||||
|
"""
|
||||||
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
||||||
|
self.assertEqual(expected_directions, tuple(directions))
|
||||||
|
|
||||||
|
@parameterized.expand([
|
||||||
|
((2, 2), 2, None,
|
||||||
|
' # \n / \n # / \n |/ \n # #\n \\ / '
|
||||||
|
'\n # @-# \n |/ \\ \n # #\n / \\ \n# # '),
|
||||||
|
((5, 2), 2, None, '')
|
||||||
|
])
|
||||||
|
def test_get_map_display__nodes__character(self, coord, dist, max_size, expected):
|
||||||
|
"""
|
||||||
|
Get sub-part of map with node-mode.
|
||||||
|
|
||||||
|
"""
|
||||||
|
mapstr = self.map.get_map_display(coord, dist=dist, mode='nodes', character='@',
|
||||||
|
max_size=max_size)
|
||||||
|
print(repr(mapstr))
|
||||||
|
self.assertEqual(expected, mapstr)
|
||||||
|
|
||||||
|
class TestMap5(TestCase):
|
||||||
|
"""
|
||||||
|
Test Map5 - Map with + and x crossing links
|
||||||
|
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
self.map = mapsystem.Map({"map": MAP5})
|
||||||
|
|
||||||
|
def test_str_output(self):
|
||||||
|
"""Check the display_map"""
|
||||||
|
stripped_map = "\n".join(line.rstrip() for line in str(self.map).split('\n'))
|
||||||
|
self.assertEqual(MAP5_DISPLAY, stripped_map)
|
||||||
|
|
||||||
|
@parameterized.expand([
|
||||||
|
((1, 0), (1, 2), ('n',)), # cross + vertically
|
||||||
|
((0, 1), (2, 1), ('e',)), # cross + horizontally
|
||||||
|
((4, 1), (1, 0), ('w', 'w', 'n', 'e', 's')),
|
||||||
|
((1, 2), (2, 3), ('ne', )), # cross x
|
||||||
|
((1, 2), (2, 3), ('ne', )),
|
||||||
|
((2, 2), (0, 4), ('w', 'ne', 'nw', 'w')),
|
||||||
|
])
|
||||||
|
def test_shortest_path(self, startcoord, endcoord, expected_directions):
|
||||||
|
"""
|
||||||
|
Test shortest-path calculations throughout the grid.
|
||||||
|
|
||||||
|
"""
|
||||||
|
directions, _ = self.map.get_shortest_path(startcoord, endcoord)
|
||||||
|
self.assertEqual(expected_directions, tuple(directions))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue