|
@@ -172,7 +172,9 @@ class Grid(Base):
|
|
|
|
|
|
|
|
for s in self.owned_ships:
|
|
for s in self.owned_ships:
|
|
|
s.allies = [other for other in self.owned_ships if other is not s]
|
|
s.allies = [other for other in self.owned_ships if other is not s]
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ self.update_moving_costs()
|
|
|
|
|
+
|
|
|
grav_center = self.barrels_gravity_center()
|
|
grav_center = self.barrels_gravity_center()
|
|
|
for b in self.barrels:
|
|
for b in self.barrels:
|
|
|
b.dispersal = Grid.manhattan(grav_center, b.pos) if grav_center != None else 0
|
|
b.dispersal = Grid.manhattan(grav_center, b.pos) if grav_center != None else 0
|
|
@@ -181,6 +183,9 @@ class Grid(Base):
|
|
|
|
|
|
|
|
for s in self.owned_ships:
|
|
for s in self.owned_ships:
|
|
|
|
|
|
|
|
|
|
+ s._can_move = {c: (s.moving_cost(*c) < 1000) for c in [s.front, s.front_left, s.left, s.front_right,
|
|
|
|
|
+ s.right, s.back_left, s.back_right]}
|
|
|
|
|
+
|
|
|
for b in self.barrels:
|
|
for b in self.barrels:
|
|
|
obj = GetBarrel(b)
|
|
obj = GetBarrel(b)
|
|
|
obj.eval(s.next_pos if s.speed else s.prow, s.orientation)
|
|
obj.eval(s.next_pos if s.speed else s.prow, s.orientation)
|
|
@@ -191,9 +196,6 @@ class Grid(Base):
|
|
|
obj.eval(s.next_pos, s.orientation)
|
|
obj.eval(s.next_pos, s.orientation)
|
|
|
s.ennemies.put(obj)
|
|
s.ennemies.put(obj)
|
|
|
|
|
|
|
|
- self.update_moving_costs()
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
def at(self, x, y):
|
|
def at(self, x, y):
|
|
|
try:
|
|
try:
|
|
|
return self.index[(x, y)]
|
|
return self.index[(x, y)]
|
|
@@ -242,10 +244,14 @@ class Grid(Base):
|
|
|
dist = self.manhattan(ship.pos, other.pos)
|
|
dist = self.manhattan(ship.pos, other.pos)
|
|
|
if dist > 8:
|
|
if dist > 8:
|
|
|
continue
|
|
continue
|
|
|
- for c in self.neighbors(*other.pos):
|
|
|
|
|
- ship._moving_costs[c] += 100 * abs(3 - other.speed)
|
|
|
|
|
- for c in self.zone(other.next_pos, 4):
|
|
|
|
|
- ship._moving_costs[c] += 20
|
|
|
|
|
|
|
+ if not other.speed:
|
|
|
|
|
+ for c in other.area:
|
|
|
|
|
+ ship._moving_costs[c] += 1000
|
|
|
|
|
+ else:
|
|
|
|
|
+ for c in self.neighbors(*other.pos):
|
|
|
|
|
+ ship._moving_costs[c] += 100 * abs(3 - other.speed)
|
|
|
|
|
+ for c in self.zone(other.next_pos, 4):
|
|
|
|
|
+ ship._moving_costs[c] += 20
|
|
|
|
|
|
|
|
def shooting_spot(self, ship, target):
|
|
def shooting_spot(self, ship, target):
|
|
|
shooting_spots = Queue()
|
|
shooting_spots = Queue()
|
|
@@ -550,8 +556,10 @@ class Ship(Entity):
|
|
|
self.left = Grid.next_cell(*self.prow, Grid.add_directions(self.orientation, 2))
|
|
self.left = Grid.next_cell(*self.prow, Grid.add_directions(self.orientation, 2))
|
|
|
self.front_right = Grid.next_cell(*self.prow, Grid.add_directions(self.orientation, -1))
|
|
self.front_right = Grid.next_cell(*self.prow, Grid.add_directions(self.orientation, -1))
|
|
|
self.right = Grid.next_cell(*self.prow, Grid.add_directions(self.orientation, -2))
|
|
self.right = Grid.next_cell(*self.prow, Grid.add_directions(self.orientation, -2))
|
|
|
- self.back_left = Grid.next_cell(*self.stern, Grid.add_directions(self.orientation, 2))
|
|
|
|
|
- self.back_right = Grid.next_cell(*self.stern, Grid.add_directions(self.orientation, -2))
|
|
|
|
|
|
|
+ self.back_left = Grid.next_cell(*self.stern, Grid.add_directions(self.orientation, 1))
|
|
|
|
|
+ self.back_right = Grid.next_cell(*self.stern, Grid.add_directions(self.orientation, -1))
|
|
|
|
|
+
|
|
|
|
|
+ self._can_move = {}
|
|
|
|
|
|
|
|
self.mobility_zone = list(set(self.area + self.next_area))
|
|
self.mobility_zone = list(set(self.area + self.next_area))
|
|
|
|
|
|
|
@@ -632,25 +640,18 @@ class Ship(Entity):
|
|
|
def moving_cost(self, x, y):
|
|
def moving_cost(self, x, y):
|
|
|
return self._moving_costs.get((x, y), 1000)
|
|
return self._moving_costs.get((x, y), 1000)
|
|
|
|
|
|
|
|
- def cant_move(self):
|
|
|
|
|
-
|
|
|
|
|
- blocked = {c: (self.moving_cost(*c) >= 1000) for c in [self.front, self.front_left, self.left,
|
|
|
|
|
- self.front_right, self.right,
|
|
|
|
|
- self.back_left, self.back_right]}
|
|
|
|
|
-
|
|
|
|
|
- if all(blocked[i] for i in [self.front, self.front_left, self.front_right, self.left, self.right]):
|
|
|
|
|
- # surrounded
|
|
|
|
|
- return True
|
|
|
|
|
- elif (blocked[self.front_left] and blocked[self.left]) or (blocked[self.front_right] and blocked[self.right]):
|
|
|
|
|
- # side by side
|
|
|
|
|
- return True
|
|
|
|
|
- elif blocked[self.front] and ((blocked[self.front_left] and blocked[self.back_right]) or (blocked[self.front_right] and blocked[self.back_left])):
|
|
|
|
|
- # cannot go front or turn
|
|
|
|
|
- return True
|
|
|
|
|
-
|
|
|
|
|
- return False
|
|
|
|
|
-
|
|
|
|
|
|
|
+ def can_turn_left(self):
|
|
|
|
|
+ return self._can_move[self.left] and self._can_move[self.back_right]
|
|
|
|
|
+
|
|
|
|
|
+ def can_turn_right(self):
|
|
|
|
|
+ return self._can_move[self.right] and self._can_move[self.back_left]
|
|
|
|
|
|
|
|
|
|
+ def can_move_fwd(self):
|
|
|
|
|
+ return self._can_move[self.front]
|
|
|
|
|
+
|
|
|
|
|
+ def can_move(self):
|
|
|
|
|
+ return self.can_move_fwd() or self.can_turn_left() or self.can_turn_left()
|
|
|
|
|
+
|
|
|
def move(self, *args, **kwargs):
|
|
def move(self, *args, **kwargs):
|
|
|
try:
|
|
try:
|
|
|
self._move(*args, **kwargs)
|
|
self._move(*args, **kwargs)
|
|
@@ -658,13 +659,15 @@ class Ship(Entity):
|
|
|
except DidNotAct:
|
|
except DidNotAct:
|
|
|
return False
|
|
return False
|
|
|
|
|
|
|
|
-
|
|
|
|
|
def _move(self, path):
|
|
def _move(self, path):
|
|
|
|
|
|
|
|
|
|
+ log(self._can_move, self.can_turn_left(), self.can_turn_right(), self.can_move_fwd())
|
|
|
|
|
+
|
|
|
if path is None:
|
|
if path is None:
|
|
|
- log(f"(!) broken: automove to {self.goto}")
|
|
|
|
|
- self.auto_move(*self.goto)
|
|
|
|
|
- return
|
|
|
|
|
|
|
+ if self.can_move():
|
|
|
|
|
+ log(f"(!) broken: automove to {self.goto}")
|
|
|
|
|
+ self.auto_move(*self.goto)
|
|
|
|
|
+ return
|
|
|
elif not path:
|
|
elif not path:
|
|
|
raise DidNotAct()
|
|
raise DidNotAct()
|
|
|
|
|
|
|
@@ -674,23 +677,24 @@ class Ship(Entity):
|
|
|
next_flag = next(flags, last_flag)
|
|
next_flag = next(flags, last_flag)
|
|
|
afternext_flag = next(flags, last_flag)
|
|
afternext_flag = next(flags, last_flag)
|
|
|
|
|
|
|
|
- log(next_flag, afternext_flag, last_flag)
|
|
|
|
|
-
|
|
|
|
|
if not self.speed:
|
|
if not self.speed:
|
|
|
diff = Grid.diff_directions(self.orientation, path[0].orientation)
|
|
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()
|
|
|
|
|
- return
|
|
|
|
|
|
|
+ if self.can_turn_left():
|
|
|
|
|
+ self.turn_left()
|
|
|
|
|
+ return
|
|
|
elif diff < 0:
|
|
elif diff < 0:
|
|
|
- self.turn_right()
|
|
|
|
|
- return
|
|
|
|
|
|
|
+ if self.can_turn_right():
|
|
|
|
|
+ self.turn_right()
|
|
|
|
|
+ return
|
|
|
else:
|
|
else:
|
|
|
# start straight
|
|
# start straight
|
|
|
- self.speed_up()
|
|
|
|
|
- return
|
|
|
|
|
|
|
+ if self.can_move_fwd():
|
|
|
|
|
+ self.speed_up()
|
|
|
|
|
+ return
|
|
|
|
|
|
|
|
elif self.speed == self.MAX_SPEED:
|
|
elif self.speed == self.MAX_SPEED:
|
|
|
|
|
|
|
@@ -953,10 +957,6 @@ while True:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- ### special: avoid cannonballs
|
|
|
|
|
- danger = [c.pos for c in grid.cannonballs if c.countdown <= 1]
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
### Process
|
|
### Process
|
|
|
log("# Processing")
|
|
log("# Processing")
|
|
|
|
|
|
|
@@ -965,11 +965,6 @@ while True:
|
|
|
log("No target: wait")
|
|
log("No target: wait")
|
|
|
ship.wait()
|
|
ship.wait()
|
|
|
|
|
|
|
|
- if ship.cant_move():
|
|
|
|
|
- log("blocked... fire!")
|
|
|
|
|
- if ship.fire_at_will(ship.target_ennemy.target, allies=grid.owned_ships):
|
|
|
|
|
- continue
|
|
|
|
|
-
|
|
|
|
|
if ship.move(ship.path):
|
|
if ship.move(ship.path):
|
|
|
continue
|
|
continue
|
|
|
|
|
|