home · contact · privacy
Refactor and optimize FOV algorithm.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 30 Jan 2019 23:37:00 +0000 (00:37 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 30 Jan 2019 23:37:00 +0000 (00:37 +0100)
server_/game.py
server_/map_.py

index 0974f1b7050c22891087d7fc57e1e72e92035160..aafc7402017734031b287cf7a1c474123be4f19d 100644 (file)
@@ -118,13 +118,15 @@ class Thing(game_common.Thing):
         dijkstra_map.terrain = [n_max for i in range(dijkstra_map.size_i)]
         dijkstra_map[target] = 0
         shrunk = True
+        stencil = self.get_stencil()
         while shrunk:
             shrunk = False
             for pos in dijkstra_map:
-                if self.world.map_[pos] != '.':
+                if stencil[pos] != '.':
                     continue
-                neighbors = dijkstra_map.get_neighbors(pos)
-                for yx in neighbors:
+                neighbors = dijkstra_map.get_neighbors(tuple(pos))
+                for direction in neighbors:
+                    yx = neighbors[direction]
                     if yx is not None and dijkstra_map[yx] < dijkstra_map[pos] - 1:
                         dijkstra_map[pos] = dijkstra_map[yx] + 1
                         shrunk = True
@@ -139,9 +141,10 @@ class Thing(game_common.Thing):
         #            else:
         #                f.write('~')
         #        f.write('\n')
-        neighbors = dijkstra_map.get_neighbors(self.position)
+        neighbors = dijkstra_map.get_neighbors(tuple(self.position))
         n = n_max
-        dirs = dijkstra_map.get_directions()
+        #print('DEBUG', self.position, neighbors)
+        #dirs = dijkstra_map.get_directions()
         #print('DEBUG dirs', dirs)
         #print('DEBUG neighbors', neighbors)
         #debug_scores = []
@@ -151,15 +154,17 @@ class Thing(game_common.Thing):
         #    else:
         #        debug_scores += [dijkstra_map[pos]]
         #print('DEBUG debug_scores', debug_scores)
-        direction = None
-        for i_dir in range(len(neighbors)):
-            pos = neighbors[i_dir]
-            if pos is not None and dijkstra_map[pos] < n:
-                n = dijkstra_map[pos]
-                direction = dirs[i_dir]
+        target_direction = None
+        for direction in neighbors:
+            yx = neighbors[direction]
+            if yx is not None:
+                n_new = dijkstra_map[yx]
+                if n_new < n:
+                    n = n_new
+                    target_direction = direction
         #print('DEBUG result', direction)
-        if direction:
-            self.set_task('MOVE', (direction,))
+        if target_direction:
+            self.set_task('MOVE', (target_direction,))
             #self.world.game.io.send('would move ' + direction)
 
     def decide_task(self):
index 35d29c6b56da95fd2f25c4e35f4e85a3ff419da8..dd47be5dcce61f976160e92480ad0d02efbde70d 100644 (file)
@@ -50,6 +50,21 @@ class Map(game_common.Map):
                 directions += [name[5:]]
         return directions
 
+    def get_neighbors(self, pos):
+        neighbors = {}
+        if not hasattr(self, 'neighbors_to'):
+            self.neighbors_to = {}
+        if pos in self.neighbors_to:
+            return self.neighbors_to[pos]
+        for direction in self.get_directions():
+            neighbors[direction] = None
+            try:
+                neighbors[direction] = self.move(pos, direction)
+            except server_.game.GameError:
+                pass
+        self.neighbors_to[pos] = neighbors
+        return neighbors
+
     def new_from_shape(self, init_char):
         import copy
         new_map = copy.deepcopy(self)
@@ -110,34 +125,6 @@ class MapHex(Map):
         else:
             return [start_pos[0] + 1, start_pos[1] + 1]
 
-    def get_neighbors(self, pos):
-        # DOWNLEFT, DOWNRIGHT, LEFT, RIGHT, UPLEFT, UPRIGHT (alphabetically)
-        neighbors = [None, None, None, None, None, None]  # e, d, c, x, s, w
-        if pos[1] > 0:
-            neighbors[2] = [pos[0], pos[1] - 1]
-        if pos[1] < self.size[1] - 1:
-            neighbors[3] = [pos[0], pos[1] + 1]
-        # x, c, s, d, w, e  # 3->0, 2->1, 5->4, 0->5
-        if pos[0] % 2 == 1:
-            if pos[0] > 0 and pos[1] > 0:
-                neighbors[4] = [pos[0] - 1, pos[1] - 1]
-            if pos[0] < self.size[0] - 1 and pos[1] > 0:
-                neighbors[0] = [pos[0] + 1, pos[1] - 1]
-            if pos[0] > 0:
-                neighbors[5] = [pos[0] - 1, pos[1]]
-            if pos[0] < self.size[0] - 1:
-                neighbors[1] = [pos[0] + 1, pos[1]]
-        else:
-            if pos[0] > 0 and pos[1] < self.size[1] - 1:
-                neighbors[5] = [pos[0] - 1, pos[1] + 1]
-            if pos[0] < self.size[0] - 1 and pos[1] < self.size[1] - 1:
-                neighbors[1] = [pos[0] + 1, pos[1] + 1]
-            if pos[0] > 0:
-                neighbors[4] = [pos[0] - 1, pos[1]]
-            if pos[0] < self.size[0] - 1:
-                neighbors[0] = [pos[0] + 1, pos[1]]
-        return neighbors
-
 
 class MapSquare(Map):
 
@@ -151,19 +138,6 @@ class MapSquare(Map):
     def move_DOWN(self, start_pos):
         return [start_pos[0] + 1, start_pos[1]]
 
-    def get_neighbors(self, pos):
-        # DOWN, LEFT, RIGHT, UP  (alphabetically)
-        neighbors = [None, None, None, None]
-        if pos[0] > 0:
-            neighbors[3] = [pos[0] - 1, pos[1]]
-        if pos[1] > 0:
-            neighbors[1] = [pos[0], pos[1] - 1]
-        if pos[0] < self.size[0] - 1:
-            neighbors[0] = [pos[0] + 1, pos[1]]
-        if pos[1] < self.size[1] - 1:
-            neighbors[2] = [pos[0], pos[1] + 1]
-        return neighbors
-
 
 class FovMap: