Map-tested diagonals and crossover links

This commit is contained in:
Griatch 2021-06-08 21:46:05 +02:00
parent 3c8003ee63
commit 0e73380ede
2 changed files with 174 additions and 10 deletions

View file

@ -76,7 +76,7 @@ See `./example_maps.py` for some empty grid areas to start from.
from collections import defaultdict
try:
from scipy.sparse.csgraph import dijkstra
from scipy.sparse.csgraph import dijkstra, breadth_first_order
from scipy.sparse import csr_matrix
from scipy import zeros
except ImportError as err:
@ -105,7 +105,7 @@ _MAPSCAN = {
"s": (0, -1),
"sw": (-1, -1),
"w": (-1, 0),
"nw": (1, -1)
"nw": (-1, 1)
}
_BIG = 999999999999
@ -392,6 +392,9 @@ class MapLink:
# from evennia import set_trace;set_trace()
end_direction = self.get_directions(start_direction, xygrid).get(start_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 "
f"from {start_direction}, but does not link that way.")
@ -884,6 +887,10 @@ class Map:
startnode = self.get_node_from_coord(startcoord)
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:
self._calculate_path_matrix()

View file

@ -62,10 +62,86 @@ MAP2_DISPLAY = """
#-#-#-#
""".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):
"""
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
@parameterized.expand([
((0, 0), '# \n| \n@-#'),
((0, 1), '@-#\n| \n# '),
((1, 0), ' #\n |\n#-@'),
((1, 1), '#-@\n |\n #'),
((0, 0), 1, '# \n| \n@-#'),
((0, 1), 1, '@-#\n| \n# '),
((1, 0), 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.
"""
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)
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):
@ -251,3 +328,83 @@ class TestMap2(TestCase):
mapstr = self.map.get_map_display(coord, dist=dist, mode='nodes', character='@',
max_size=max_size)
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))