Skip to content

Commit b0c8d84

Browse files
committed
Convert path example into doctest, add more examples.
1 parent 52a5738 commit b0c8d84

1 file changed

Lines changed: 96 additions & 13 deletions

File tree

tcod/path.py

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,13 +1159,26 @@ def traversal(self) -> np.ndarray:
11591159
Example::
11601160
11611161
# This example demonstrates the purpose of the traversal array.
1162-
# In real code Pathfinder.path_from(...) should be used instead.
1163-
pf # Resolved 2D Pathfinder instance.
1164-
i, j = (3, 3) # Starting index.
1165-
path = [(i, j)] # List of nodes from the start to the root.
1166-
while not (pf.traversal[i, j] == (i, j)).all():
1167-
i, j = pf.traversal[i, j]
1168-
path.append((i, j))
1162+
>>> graph = tcod.path.SimpleGraph(
1163+
... cost=np.ones((5, 5), np.int8), cardinal=2, diagonal=3,
1164+
... )
1165+
>>> pf = tcod.path.Pathfinder(graph)
1166+
>>> pf.add_root((0, 0))
1167+
>>> pf.resolve()
1168+
>>> pf.traversal[3, 3].tolist() # Faster.
1169+
[2, 2]
1170+
>>> pf.path_from((3, 3))[1].tolist() # Slower.
1171+
[2, 2]
1172+
>>> i, j = (3, 3) # Starting index.
1173+
>>> path = [(i, j)] # List of nodes from the start to the root.
1174+
>>> while not (pf.traversal[i, j] == (i, j)).all():
1175+
... i, j = pf.traversal[i, j]
1176+
... path.append((i, j))
1177+
>>> path # Slower.
1178+
[(3, 3), (2, 2), (1, 1), (0, 0)]
1179+
>>> pf.path_from((3, 3)).tolist() # Faster.
1180+
[[3, 3], [2, 2], [1, 1], [0, 0]]
1181+
11691182
11701183
The above example is slow and will not detect infinite loops. Use
11711184
:any:`path_from` or :any:`path_to` when you need to get a path.
@@ -1230,9 +1243,13 @@ def _update_heuristic(self, goal_ij: Optional[Tuple[int, ...]]) -> bool:
12301243
def rebuild_frontier(self) -> None:
12311244
"""Reconstruct the frontier using the current distance array.
12321245
1233-
This is needed if the :any:`distance` array is changed manually.
1246+
If you are using :any:`add_root` then you will not need to call this
1247+
function. This is only needed if the :any:`distance` array has been
1248+
modified manually.
1249+
12341250
After you are finished editing :any:`distance` you must call this
1235-
function before calling :any:`resolve`, :any:`path_from`, etc.
1251+
function before calling :any:`resolve` or any function which calls
1252+
:any:`resolve` implicitly such as :any:`path_from` or :any:`path_to`.
12361253
"""
12371254
lib.TCOD_frontier_clear(self._frontier_p)
12381255
self._update_heuristic(None)
@@ -1254,8 +1271,38 @@ def resolve(self, goal: Optional[Tuple[int, ...]] = None) -> None:
12541271
12551272
If `goal` is given an index then it will attempt to resolve the
12561273
:any:`distance` and :any:`traversal` arrays only up to the `goal`.
1257-
If the graph has set a heuristic then it will be used and this call
1258-
will be similar to `A*`.
1274+
If the graph has set a heuristic then it will be used with a process
1275+
similar to `A*`.
1276+
1277+
Example::
1278+
1279+
>>> graph = tcod.path.SimpleGraph(
1280+
... cost=np.ones((4, 4), np.int8), cardinal=2, diagonal=3,
1281+
... )
1282+
>>> pf = tcod.path.Pathfinder(graph)
1283+
>>> pf.distance
1284+
array([[2147483647, 2147483647, 2147483647, 2147483647],
1285+
[2147483647, 2147483647, 2147483647, 2147483647],
1286+
[2147483647, 2147483647, 2147483647, 2147483647],
1287+
[2147483647, 2147483647, 2147483647, 2147483647]]...)
1288+
>>> pf.add_root((0, 0))
1289+
>>> pf.distance
1290+
array([[ 0, 2147483647, 2147483647, 2147483647],
1291+
[2147483647, 2147483647, 2147483647, 2147483647],
1292+
[2147483647, 2147483647, 2147483647, 2147483647],
1293+
[2147483647, 2147483647, 2147483647, 2147483647]]...)
1294+
>>> pf.resolve((1, 1)) # Resolve up to (1, 1) as A*.
1295+
>>> pf.distance # Partially resolved distance.
1296+
array([[ 0, 2, 6, 2147483647],
1297+
[ 2, 3, 5, 2147483647],
1298+
[ 6, 5, 6, 2147483647],
1299+
[2147483647, 2147483647, 2147483647, 2147483647]]...)
1300+
>>> pf.resolve() # Resolve the full graph as Dijkstra.
1301+
>>> pf.distance # Fully resolved distance.
1302+
array([[0, 2, 4, 6],
1303+
[2, 3, 5, 7],
1304+
[4, 5, 6, 8],
1305+
[6, 7, 8, 9]]...)
12591306
"""
12601307
if goal is not None:
12611308
goal = tuple(goal) # Check for bad input.
@@ -1289,7 +1336,24 @@ def path_from(self, index: Tuple[int, ...]) -> np.ndarray:
12891336
12901337
A common usage is to slice off the starting point and convert the array
12911338
into a list.
1292-
"""
1339+
1340+
Example::
1341+
1342+
>>> cost = np.ones((5, 5), dtype=np.int8)
1343+
>>> cost[:, 3:] = 0
1344+
>>> graph = tcod.path.SimpleGraph(cost=cost, cardinal=2, diagonal=3)
1345+
>>> pf = tcod.path.Pathfinder(graph)
1346+
>>> pf.add_root((0, 0))
1347+
>>> pf.path_from((2, 2)).tolist()
1348+
[[2, 2], [1, 1], [0, 0]]
1349+
>>> pf.path_from((2, 2))[1:].tolist() # Exclude the starting point by slicing the array.
1350+
[[1, 1], [0, 0]]
1351+
>>> pf.path_from((4, 4)).tolist() # Blocked paths will only have the index point.
1352+
[[4, 4]]
1353+
>>> pf.path_from((4, 4))[1:].tolist() # Exclude the starting point so that a blocked path is an empty list.
1354+
[]
1355+
1356+
""" # noqa: E501
12931357
index = tuple(index) # Check for bad input.
12941358
if len(index) != self._graph._ndim:
12951359
raise TypeError(
@@ -1319,5 +1383,24 @@ def path_to(self, index: Tuple[int, ...]) -> np.ndarray:
13191383
13201384
See :any:`path_from`.
13211385
This is an alias for ``path_from(...)[::-1]``.
1322-
"""
1386+
1387+
This is the method to call when the root is an entity to move to a
1388+
position rather than a destination itself.
1389+
1390+
Example::
1391+
1392+
>>> graph = tcod.path.SimpleGraph(
1393+
... cost=np.ones((5, 5), np.int8), cardinal=2, diagonal=3,
1394+
... )
1395+
>>> pf = tcod.path.Pathfinder(graph)
1396+
>>> pf.add_root((0, 0))
1397+
>>> pf.path_to((0, 0)).tolist() # This method always returns at least one point.
1398+
[[0, 0]]
1399+
>>> pf.path_to((3, 3)).tolist() # Always includes both ends on a valid path.
1400+
[[0, 0], [1, 1], [2, 2], [3, 3]]
1401+
>>> pf.path_to((3, 3))[1:].tolist() # Exclude the starting point by slicing the array.
1402+
[[1, 1], [2, 2], [3, 3]]
1403+
>>> pf.path_to((0, 0))[1:].tolist() # Exclude the starting point so that a blocked path is an empty list.
1404+
[]
1405+
""" # noqa: E501
13231406
return self.path_from(index)[::-1]

0 commit comments

Comments
 (0)