Skip to content

Commit fc6fe3f

Browse files
General small optimizations to the core engine.
1 parent d49a650 commit fc6fe3f

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

pacai/core/board.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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:

pacai/core/gamestate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ def copy(self) -> 'GameState':
104104
new_state = copy.copy(self)
105105

106106
new_state.board = self.board.copy()
107+
new_state.agent_actions = {agent_index: actions.copy() for (agent_index, actions) in self.agent_actions.items()}
107108
new_state.move_delays = self.move_delays.copy()
108109
new_state.tickets = self.tickets.copy()
109-
new_state.agent_actions = {agent_index: actions.copy() for (agent_index, actions) in self.agent_actions.items()}
110110

111111
return new_state
112112

pacai/core/ticket.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Ticket(pacai.util.json.DictConverter):
66
"""
77
An agent's Ticket determines when they will move next.
88
A ticket is a tuple of three values: (next move time, last move time, number of moves).
9+
Tickets should be treated as immutable.
910
The agent with the lowest ticket (starting with the first value and moving to the next on a tie) gets to move next.
1011
All "time" values represented by a ticket are abstract and do not relate to any actual time units.
1112
"""

pacai/pacman/gamestate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def is_scared(self, agent_index: int = -1) -> bool:
8686
if (agent_index == -1):
8787
agent_index = self.agent_index
8888

89-
return self.scared_timers.get(agent_index, 0) > 0
89+
return ((agent_index in self.scared_timers) and (self.scared_timers[agent_index] > 0))
9090

9191
def compute_move_delay(self, agent_index: int) -> int:
9292
move_delay = super().compute_move_delay(agent_index)

0 commit comments

Comments
 (0)