@@ -359,6 +359,15 @@ def __init__(self,
359359 self ._walls : set [Position ] = set ()
360360 """ The walls for this board. """
361361
362+ self ._neighbor_cache : dict [Position , list [tuple [pacai .core .action .Action , Position ]]] = {}
363+ """
364+ Keep a cache of all neighbor locations.
365+ Note that neighbors only depend on the size of the board and walls.
366+ Computing neighbors is a high-throughput activity, and therefore justifies a cache.
367+ Neighbors will be shallow copied when a board is copied,
368+ therefore all successor boards will share the same cache.
369+ """
370+
362371 self ._nonwall_objects : dict [Marker , set [Position ]] = {}
363372 """ All the non-wall objects that appear on the board. """
364373
@@ -533,7 +542,11 @@ def remove_marker(self, marker: Marker, position: Position) -> None:
533542 self ._check_bounds (position )
534543 self ._copy_on_write ()
535544
536- self ._nonwall_objects .get (marker , set ()).discard (position )
545+ markers = self ._nonwall_objects .get (marker )
546+ if (markers is None ):
547+ return
548+
549+ markers .discard (position )
537550
538551 def place_marker (self , marker : Marker , position : Position ) -> None :
539552 """
@@ -553,8 +566,14 @@ def get_neighbors(self, position: Position) -> list[tuple[pacai.core.action.Acti
553566 Get positions that are directly touching (via cardinal directions) the given position
554567 without being inside a wall,
555568 and the action it would take to get there.
569+
570+ Note that this is a high-throughput piece of code, and may contain optimizations.
556571 """
557572
573+ # Check the neighbor cache.
574+ if (position in self ._neighbor_cache ):
575+ return self ._neighbor_cache [position ]
576+
558577 neighbors = []
559578 for (action , offset ) in CARDINAL_OFFSETS .items ():
560579 neighbor = position .add (offset )
@@ -567,6 +586,9 @@ def get_neighbors(self, position: Position) -> list[tuple[pacai.core.action.Acti
567586
568587 neighbors .append ((action , neighbor ))
569588
589+ # Save to the neighbor cache.
590+ self ._neighbor_cache [position ] = neighbors
591+
570592 return neighbors
571593
572594 def get_adjacency (self , position : Position , marker : Marker ) -> AdjacencyString :
0 commit comments