Skip to content

Commit f6431c9

Browse files
committed
Add Pathfinder.traversal and more documentation.
1 parent 8941122 commit f6431c9

1 file changed

Lines changed: 39 additions & 4 deletions

File tree

tcod/path.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ def hillclimb2d(
604604

605605

606606
def _world_array(shape: Tuple[int, ...], dtype: Any = np.int32) -> np.ndarray:
607+
"""Return an array where ``ij == arr[ij]``."""
607608
return np.ascontiguousarray(
608609
np.transpose(
609610
np.meshgrid(
@@ -615,14 +616,16 @@ def _world_array(shape: Tuple[int, ...], dtype: Any = np.int32) -> np.ndarray:
615616
)
616617

617618

618-
def _as_hashable(obj: Any) -> Any:
619+
def _as_hashable(obj: Optional[np.ndarray]) -> Optional[Any]:
620+
"""Return NumPy arrays as a more hashable form."""
619621
if obj is None:
620622
return obj
621623
return obj.ctypes.data, tuple(obj.shape), tuple(obj.strides)
622624

623625

624626
class Graph:
625-
"""
627+
"""A modular graph defining how a pathfinder traverses the world.
628+
626629
Example::
627630
628631
>>> import tcod
@@ -765,7 +768,8 @@ def _compile_rules(self) -> Any:
765768

766769

767770
class Pathfinder:
768-
"""
771+
"""A generic modular pathfinder.
772+
769773
.. versionadded:: 11.13
770774
"""
771775

@@ -793,16 +797,47 @@ def distance(self) -> np.ndarray:
793797
Unreachable or unresolved points will be at their maximum values.
794798
You can use :any:`numpy.iinfo` if you need to check for these.
795799
800+
Example::
801+
802+
pf # Resolved Pathfinder instance.
803+
reachable = pf.distance != numpy.iinfo(pf.distance.dtype).max
804+
reachable # A boolean array of reachable area.
805+
796806
You may edit this array manually, but the pathfinder won't know of
797807
your changes until :any:`rebuild_frontier` is called.
798808
"""
799809
return self._distance
800810

811+
@property
812+
def traversal(self) -> np.ndarray:
813+
"""An array used to generate paths from any point to the nearest root.
814+
815+
This array is stored in row-major "C" order. It has an extra
816+
dimension which includes the index of the next path.
817+
818+
Example::
819+
820+
# This example demonstrates the purpose of the traversal array.
821+
# In real code Pathfinder.path_from(...) should be used instead.
822+
pf # Resolved 2D Pathfinder instance.
823+
i, j = (3, 3) # Starting index.
824+
path = [(i, j)] # List of nodes from the start to the root.
825+
while not (pf.traversal[i, j] == (i, j)).all():
826+
i, j = pf.traversal[i, j]
827+
path.append((i, j))
828+
829+
The above example is slow and will not detect infinite loops. Use
830+
:any:`path_from` or :any:`path_to` when you need to get a path.
831+
832+
As the pathfinder is resolved this array is filled
833+
"""
834+
return self._travel
835+
801836
def clear(self) -> None:
802837
"""Reset the pathfinder to its initial state.
803838
804839
This sets all values on the :any:`distance` array to their maximum
805-
values. Use :any:`numpy.iinfo` if you need to check these.
840+
value.
806841
"""
807842
self._distance[...] = np.iinfo(self._distance.dtype).max
808843
self._travel = _world_array(self._graph._shape)

0 commit comments

Comments
 (0)