home · contact · privacy
Only calculate DijkstraMap until reachable targets.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 16 Dec 2020 18:28:45 +0000 (19:28 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 16 Dec 2020 18:28:45 +0000 (19:28 +0100)
plomrogue/mapping.py
plomrogue/things.py

index 29078d87c0b9d71ef9ee2d8616e862888b73f705..707111263d884b21508ba536fc02b95e2af66677 100644 (file)
@@ -256,15 +256,21 @@ class SourcedMap(Map):
 
 class DijkstraMap(SourcedMap):
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, potential_targets, *args, **kwargs):
         # TODO: check potential optimizations:
         # - somehow ignore tiles that have the lowest possible value (we can
         #   compare with a precalculated map for given starting position)
         # - check if Python offers more efficient data structures to use here
-        # - shorten radius to nearest possible target
         super().__init__(*args, **kwargs)
         self.terrain = [255] * self.size_i
         self[self.center] = 0
+        targets = []
+        for target_yxyx in potential_targets:
+            target = self.target_yx(*target_yxyx)
+            if target == self.center:
+                continue
+            if self.inside(target):
+                targets += [target]
 
         def work_tile(position_i):
             shrunk_test = False
@@ -280,18 +286,21 @@ class DijkstraMap(SourcedMap):
 
         # TODO: refactor with FovMap.circle_out()
         shrunk = True
-        while shrunk:
+        while shrunk and len(targets) > 0:
             shrunk = False
             yx = self.center
             distance = 1
-            while distance <= self.radius:
+            while distance <= self.radius and len(targets) > 0:
                 yx = self.geometry.basic_circle_out_move(yx, 'RIGHT')
                 for dir_i in range(len(self.geometry.circle_out_directions)):
                     for dir_progress in range(distance):
                         direction = self.geometry.circle_out_directions[dir_i]
                         yx = self.geometry.circle_out_move(yx, direction)
                         position_i = self.get_position_index(yx)
-                        shrunk = True if work_tile(position_i) else shrunk
+                        cur_shrunk = work_tile(position_i)
+                        if cur_shrunk and yx in targets:
+                            targets.remove(yx)
+                        shrunk = shrunk or cur_shrunk
                 distance += 1
         # print('DEBUG Dijkstra')
         # line_to_print = []
index 950a777f0bc951defb35f0f32cefe912f1008e25..dd14db5b657352c16d2a0db0adc1e175db4a2b53 100644 (file)
@@ -70,10 +70,11 @@ class Thing(ThingBase):
 
         largest_audible_distance = 20
         obstacles = [t.position for t in self.game.things if t.blocks_sound]
+        targets = [t.position for t in self.game.things if t.type_ == 'Player']
         sound_blockers = self.game.get_sound_blockers()
-        dijkstra_map = DijkstraMap(sound_blockers, obstacles, self.game.maps,
-                                   self.position, largest_audible_distance,
-                                   self.game.get_map)
+        dijkstra_map = DijkstraMap(targets, sound_blockers, obstacles,
+                                   self.game.maps, self.position,
+                                   largest_audible_distance, self.game.get_map)
         url_limits = []
         for m in re.finditer('https?://[^\s]+', msg):
             url_limits += [m.start(), m.end()]