|
@@ -397,12 +397,20 @@ class Grid(Base):
|
|
|
return result
|
|
return result
|
|
|
|
|
|
|
|
# pathfinding
|
|
# 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()
|
|
nodes = Queue()
|
|
|
break_on, iteration = limit, 0
|
|
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)
|
|
nodes.put(origin, 0)
|
|
|
neighbors = []
|
|
neighbors = []
|
|
@@ -417,7 +425,7 @@ class Grid(Base):
|
|
|
if previous != origin or incl_start:
|
|
if previous != origin or incl_start:
|
|
|
path.insert(0, previous)
|
|
path.insert(0, previous)
|
|
|
previous = previous.parent
|
|
previous = previous.parent
|
|
|
- return path
|
|
|
|
|
|
|
+ return inertia_path + path
|
|
|
|
|
|
|
|
neighbors = self.neighbors(*current)
|
|
neighbors = self.neighbors(*current)
|
|
|
|
|
|
|
@@ -444,10 +452,10 @@ class Grid(Base):
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
cost = current.cost + moving_cost + diff * 10
|
|
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)
|
|
priority = cost + 10 * Grid.manhattan((x, y), target)
|
|
|
|
|
|
|
@@ -661,7 +669,7 @@ class Ship(Entity):
|
|
|
return False
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
- def _move(self, path, danger=[]):
|
|
|
|
|
|
|
+ def _move(self, path):
|
|
|
|
|
|
|
|
if path is None:
|
|
if path is None:
|
|
|
log(f"(!) broken: automove to {self.goto}")
|
|
log(f"(!) broken: automove to {self.goto}")
|
|
@@ -670,45 +678,60 @@ class Ship(Entity):
|
|
|
elif not path:
|
|
elif not path:
|
|
|
raise DidNotAct()
|
|
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:
|
|
if not self.speed:
|
|
|
|
|
+ diff = Grid.diff_directions(self.orientation, path[0].orientation)
|
|
|
|
|
+
|
|
|
if diff and next_flag == 0:
|
|
if diff and next_flag == 0:
|
|
|
# start, with a direction change
|
|
# start, with a direction change
|
|
|
if diff > 0:
|
|
if diff > 0:
|
|
|
self.turn_left()
|
|
self.turn_left()
|
|
|
return
|
|
return
|
|
|
-
|
|
|
|
|
elif diff < 0:
|
|
elif diff < 0:
|
|
|
self.turn_right()
|
|
self.turn_right()
|
|
|
return
|
|
return
|
|
|
else:
|
|
else:
|
|
|
- # start, todo recto
|
|
|
|
|
|
|
+ # start straight
|
|
|
self.speed_up()
|
|
self.speed_up()
|
|
|
return
|
|
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
|
|
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
|
|
return
|
|
|
|
|
|
|
|
raise DidNotAct()
|
|
raise DidNotAct()
|
|
@@ -905,7 +928,12 @@ while True:
|
|
|
log("ERROR: No target")
|
|
log("ERROR: No target")
|
|
|
continue
|
|
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:
|
|
if ship.objective and ship.path and len(ship.path) <= 5:
|
|
|
# what to do next
|
|
# what to do next
|