瀏覽代碼

improve moving algo

olinox 6 年之前
父節點
當前提交
eff05f59e4
共有 1 個文件被更改,包括 61 次插入33 次删除
  1. 61 33
      carribean/script.py

+ 61 - 33
carribean/script.py

@@ -397,12 +397,20 @@ class Grid(Base):
         return result
 
     # pathfinding
-    def path(self, origin, orientat0, target, moving_costs={}, incl_start=False, limit=10000):
+    def path(self, start, d0, target, moving_costs={}, inertia=0, incl_start=False, limit=10000):
         nodes = Queue()
         break_on, iteration = limit, 0
         
-        origin = PathNode(*origin)
-        origin.orientation = orientat0
+        inertia_path = []
+        effective_start = start
+        for _ in range(inertia):
+            effective_start = self.next_cell(*effective_start, d0)
+            n = PathNode(*effective_start)
+            n.orientation = d0
+            inertia_path.append(n)
+        
+        origin = PathNode(*effective_start)
+        origin.orientation = d0
         
         nodes.put(origin, 0)
         neighbors = []
@@ -417,7 +425,7 @@ class Grid(Base):
                     if previous != origin or incl_start:
                         path.insert(0, previous)
                     previous = previous.parent
-                return path
+                return inertia_path + path
 
             neighbors = self.neighbors(*current)
 
@@ -444,10 +452,10 @@ class Grid(Base):
                     continue
                     
                 cost = current.cost + moving_cost + diff * 10
-#                 if diff != 0 and any(moving_costs.get(c, 1000) >= 1000 for c in neighbors):
-#                     # a direction change here is dangerous
-#                     cost += 100
-                
+                    
+                if (x, y) == effective_start and d == d0:
+                    # prefer to go right at start
+                    cost -= 10
                 
                 priority = cost + 10 * Grid.manhattan((x, y), target)
 
@@ -661,7 +669,7 @@ class Ship(Entity):
             return False
 
 
-    def _move(self, path, danger=[]):
+    def _move(self, path):
         
         if path is None:
             log(f"(!) broken: automove to {self.goto}")
@@ -670,45 +678,60 @@ class Ship(Entity):
         elif not path:
             raise DidNotAct()
         
-        # speed shall be at 1 when arriving on the "flag"
-        next_flag = next((i for i, n in enumerate(path) if n.orientation != self.orientation), None)
-        if next_flag is None:
-            next_flag = len(path)
+        # flags represent direction changes of end of the path
+        last_flag = len(path) - 1
+        flags = (i for i, n in enumerate(path) if n.orientation != self.orientation)
+        next_flag = next(flags, last_flag)
+        afternext_flag = next(flags, last_flag)
         
-        diff = Grid.diff_directions(self.orientation, path[0].orientation)
+        log(next_flag, afternext_flag, last_flag)
         
         if not self.speed:
+            diff = Grid.diff_directions(self.orientation, path[0].orientation)
+            
             if diff and next_flag == 0:
                 # start, with a direction change
                 if diff > 0:
                     self.turn_left()
                     return
-                    
                 elif diff < 0:
                     self.turn_right()
                     return
             else:
-                # start, todo recto
+                # start straight
                 self.speed_up()
                 return
         
-        elif self.speed > 1 and next_flag <= (self.speed + 1):
-            # the end of the path or a direction change is coming
-            self.slow_down()
-            return
-        
-        elif next_flag > self.MAX_SPEED + 1 and self.speed < self.MAX_SPEED:
-            # long path and no direction change coming: speed up
-            self.speed_up()
-            return
-        
-        elif diff:
-            if diff > 0:
-                self.turn_left()
+        elif self.speed == self.MAX_SPEED:
+            
+            if self.speed == next_flag and afternext_flag > (next_flag + 1): # there is at least one straight cell after this drift
+                # drift
+                diff = Grid.diff_directions(self.orientation, path[next_flag].orientation)
+                if diff > 0:
+                    self.turn_left()
+                    return
+                elif diff < 0:
+                    self.turn_right()
+                    return
+            
+            if (self.speed + 1) >= next_flag:
+                # next direction change or target will be passed at current speed
+                self.slow_down()
                 return
-                
-            elif diff < 0:
-                self.turn_right()
+
+        elif self.speed == 1:
+            
+            if self.speed == next_flag:
+                diff = Grid.diff_directions(self.orientation, path[next_flag].orientation)
+                if diff > 0:
+                    self.turn_left()
+                    return
+                elif diff < 0:
+                    self.turn_right()
+                    return
+            
+            elif next_flag > 3:
+                self.speed_up()
                 return
         
         raise DidNotAct()
@@ -905,7 +928,12 @@ while True:
             log("ERROR: No target")
             continue
         
-        ship.path = grid.path(ship.next_pos, ship.orientation, ship.goto, ship._moving_costs, limit=6000 // len(grid.owned_ships))
+        ship.path = grid.path(ship.pos, 
+                              ship.orientation, 
+                              ship.goto, 
+                              moving_costs=ship._moving_costs, 
+                              inertia=ship.speed, 
+                              limit=6000 // len(grid.owned_ships))
         
         if ship.objective and ship.path and len(ship.path) <= 5:
             # what to do next