|
@@ -187,6 +187,9 @@ class Grid(Base):
|
|
|
for s in self.ennemy_ships:
|
|
for s in self.ennemy_ships:
|
|
|
s.allies = [other for other in self.ennemy_ships if other is not s]
|
|
s.allies = [other for other in self.ennemy_ships if other is not s]
|
|
|
|
|
|
|
|
|
|
+ for s in self.ships:
|
|
|
|
|
+ s.next_positions = s.next_pos_proba(4)
|
|
|
|
|
+
|
|
|
self.update_moving_costs()
|
|
self.update_moving_costs()
|
|
|
|
|
|
|
|
grav_center = self.barrels_gravity_center()
|
|
grav_center = self.barrels_gravity_center()
|
|
@@ -250,7 +253,7 @@ class Grid(Base):
|
|
|
for m in self.mines:
|
|
for m in self.mines:
|
|
|
base_costs[m.pos] += 1000
|
|
base_costs[m.pos] += 1000
|
|
|
for c in self.cannonballs:
|
|
for c in self.cannonballs:
|
|
|
- base_costs[c.pos] += (100 + (5 - c.countdown) * 200)
|
|
|
|
|
|
|
+ base_costs[c.pos] += (100 + (6 - c.countdown) * 200)
|
|
|
|
|
|
|
|
for ship in self.ships:
|
|
for ship in self.ships:
|
|
|
ship._moving_costs = {}
|
|
ship._moving_costs = {}
|
|
@@ -265,10 +268,14 @@ class Grid(Base):
|
|
|
for c in other.area:
|
|
for c in other.area:
|
|
|
ship._moving_costs[c] += 1000
|
|
ship._moving_costs[c] += 1000
|
|
|
else:
|
|
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):
|
|
for c in self.zone(other.next_pos, 4):
|
|
|
- ship._moving_costs[c] += 20
|
|
|
|
|
|
|
+ if c in other.next_positions[1]:
|
|
|
|
|
+ if other.next_positions[1][c] > 10:
|
|
|
|
|
+ ship._moving_costs[c] += 1000
|
|
|
|
|
+ else:
|
|
|
|
|
+ ship._moving_costs[c] += 100
|
|
|
|
|
+ else:
|
|
|
|
|
+ ship._moving_costs[c] += 20
|
|
|
|
|
|
|
|
def shooting_spot(self, ship, target):
|
|
def shooting_spot(self, ship, target):
|
|
|
shooting_spots = Queue()
|
|
shooting_spots = Queue()
|
|
@@ -425,6 +432,7 @@ class Grid(Base):
|
|
|
def path(self, start, d0, target, moving_costs={}, inertia=0, 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
|
|
|
|
|
+ broken = False
|
|
|
|
|
|
|
|
inertia_path = []
|
|
inertia_path = []
|
|
|
effective_start = start
|
|
effective_start = start
|
|
@@ -443,7 +451,7 @@ class Grid(Base):
|
|
|
while nodes:
|
|
while nodes:
|
|
|
current = nodes.get()
|
|
current = nodes.get()
|
|
|
|
|
|
|
|
- if current == target:
|
|
|
|
|
|
|
+ if current == target or broken:
|
|
|
path = []
|
|
path = []
|
|
|
previous = current
|
|
previous = current
|
|
|
while previous:
|
|
while previous:
|
|
@@ -461,7 +469,8 @@ class Grid(Base):
|
|
|
|
|
|
|
|
iteration += 1
|
|
iteration += 1
|
|
|
if break_on > 0 and iteration >= break_on:
|
|
if break_on > 0 and iteration >= break_on:
|
|
|
- return None
|
|
|
|
|
|
|
+ broken = True
|
|
|
|
|
+ break
|
|
|
|
|
|
|
|
moving_cost = moving_costs.get((x, y), 1000)
|
|
moving_cost = moving_costs.get((x, y), 1000)
|
|
|
if moving_cost >= 1000:
|
|
if moving_cost >= 1000:
|
|
@@ -524,7 +533,7 @@ class Ship(Entity):
|
|
|
TURN_LEFT = 3
|
|
TURN_LEFT = 3
|
|
|
TURN_RIGHT = 4
|
|
TURN_RIGHT = 4
|
|
|
MOVES = [SLOW_DOWN, SPEED_UP, TURN_LEFT, TURN_RIGHT]
|
|
MOVES = [SLOW_DOWN, SPEED_UP, TURN_LEFT, TURN_RIGHT]
|
|
|
- COMMANDS = {SLOW_DOWN: "SLOWER", SPEED_UP: "FASTER", TURN_LEFT: "PORT", TURN_RIGHT: "STARBOARD"}
|
|
|
|
|
|
|
+ COMMANDS = {SLOW_DOWN: "SLOWER", SPEED_UP: "FASTER", TURN_LEFT: "PORT", TURN_RIGHT: "STARBOARD", None: "NONE"}
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
def __init__(self, *args, **kwargs):
|
|
|
super().__init__(*args, **kwargs)
|
|
super().__init__(*args, **kwargs)
|
|
@@ -575,6 +584,7 @@ class Ship(Entity):
|
|
|
|
|
|
|
|
self.goto = None
|
|
self.goto = None
|
|
|
self.path = []
|
|
self.path = []
|
|
|
|
|
+ self.next_positions = {}
|
|
|
|
|
|
|
|
self.area = Ship.get_area(self.x, self.y, self.orientation)
|
|
self.area = Ship.get_area(self.x, self.y, self.orientation)
|
|
|
self.prow, _, self.stern = self.area
|
|
self.prow, _, self.stern = self.area
|
|
@@ -711,17 +721,30 @@ class Ship(Entity):
|
|
|
|
|
|
|
|
def move(self, path):
|
|
def move(self, path):
|
|
|
|
|
|
|
|
|
|
+ if path:
|
|
|
|
|
+ planned = self._plan_move(path)
|
|
|
|
|
+
|
|
|
if path is None:
|
|
if path is None:
|
|
|
if self.can_move():
|
|
if self.can_move():
|
|
|
- log(f"(!) broken: automove to {self.goto}")
|
|
|
|
|
- self.auto_move(*self.goto)
|
|
|
|
|
- return True
|
|
|
|
|
|
|
+ if self.can_move_fwd():
|
|
|
|
|
+ planned = Ship.SPEED_UP
|
|
|
|
|
+ elif self.can_turn_left():
|
|
|
|
|
+ planned = Ship.TURN_LEFT
|
|
|
|
|
+ elif self.can_turn_right():
|
|
|
|
|
+ planned = Ship.TURN_RIGHT
|
|
|
|
|
+ log(f"(!) broken: automove ({planned})")
|
|
|
else:
|
|
else:
|
|
|
|
|
+ log(f"(!) broken: can not move")
|
|
|
return False
|
|
return False
|
|
|
|
|
+# if self.can_move():
|
|
|
|
|
+#
|
|
|
|
|
+# self.auto_move(*self.goto)
|
|
|
|
|
+# return True
|
|
|
|
|
+# else:
|
|
|
|
|
+# return False
|
|
|
elif not path:
|
|
elif not path:
|
|
|
return False
|
|
return False
|
|
|
|
|
|
|
|
- planned = self._plan_move(path)
|
|
|
|
|
next_move = planned
|
|
next_move = planned
|
|
|
available_moves = [next_move] + [m for m in Ship.MOVES if m != planned]
|
|
available_moves = [next_move] + [m for m in Ship.MOVES if m != planned]
|
|
|
|
|
|
|
@@ -741,6 +764,8 @@ class Ship(Entity):
|
|
|
new_pos = self.get_next_cell(new_speed)
|
|
new_pos = self.get_next_cell(new_speed)
|
|
|
new_area = self.get_area(*new_pos, new_orientation)
|
|
new_area = self.get_area(*new_pos, new_orientation)
|
|
|
|
|
|
|
|
|
|
+ log([(c, self.moving_cost(*c)) for c in new_area])
|
|
|
|
|
+
|
|
|
# special: extra-grid cells are not consider as collisions since a part of the ship can go there
|
|
# special: extra-grid cells are not consider as collisions since a part of the ship can go there
|
|
|
if any((self.moving_cost(*c) >= 1000 and c in grid) for c in new_area):
|
|
if any((self.moving_cost(*c) >= 1000 and c in grid) for c in new_area):
|
|
|
log(f"/!\ Danger: planned move <{Ship.COMMANDS[move]}> would lead to collision")
|
|
log(f"/!\ Danger: planned move <{Ship.COMMANDS[move]}> would lead to collision")
|
|
@@ -770,13 +795,9 @@ class Ship(Entity):
|
|
|
next_flag = next((i for i, n in enumerate(path) if n.orientation != self.orientation), last_flag)
|
|
next_flag = next((i for i, n in enumerate(path) if n.orientation != self.orientation), last_flag)
|
|
|
afternext_flag = next((i for i, n in enumerate(path[next_flag:]) if n.orientation != path[next_flag].orientation), last_flag)
|
|
afternext_flag = next((i for i, n in enumerate(path[next_flag:]) if n.orientation != path[next_flag].orientation), 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)
|
|
|
|
|
|
|
|
- log(self.id, self.speed, self.can_move_fwd(), self.can_turn_left(), self.can_turn_right())
|
|
|
|
|
-
|
|
|
|
|
if diff > 0 and self.last_action == "STARBOARD" or diff < 0 and self.last_action == "PORT":
|
|
if diff > 0 and self.last_action == "STARBOARD" or diff < 0 and self.last_action == "PORT":
|
|
|
# special: avoid the starting hesitation
|
|
# special: avoid the starting hesitation
|
|
|
return Ship.SPEED_UP
|
|
return Ship.SPEED_UP
|
|
@@ -1038,6 +1059,7 @@ while True:
|
|
|
log("# Processing")
|
|
log("# Processing")
|
|
|
|
|
|
|
|
for ship in grid.owned_ships:
|
|
for ship in grid.owned_ships:
|
|
|
|
|
+ log(f"---- ship {ship.id} ---")
|
|
|
if not ship.objective and not ship.target_ennemy:
|
|
if not ship.objective and not ship.target_ennemy:
|
|
|
log("No target: wait")
|
|
log("No target: wait")
|
|
|
ship.wait()
|
|
ship.wait()
|