|
|
@@ -13,14 +13,15 @@ import time
|
|
|
# * Increase the shooting rate in the second part of the game (no barrels left)
|
|
|
# * get_shooting_spots: try to intercept ennemy
|
|
|
# * make a difference between moving cost, mines, cannonballs, out of grid and other ships
|
|
|
-# * automove: priorize
|
|
|
+# * Try to temporize when taking barrel, the more the ship can wait the better
|
|
|
+# * try to cut the road to ennemies when getting barrels
|
|
|
+# * if an ennemy has more rum that every owned ship: hunt!
|
|
|
|
|
|
# Enhancements
|
|
|
# * interception trajectories
|
|
|
# * paths with extra-steps
|
|
|
# * Part 1: Speed up
|
|
|
# * Part 2: Increase shooting rate
|
|
|
-# * If an owned ship has the max stock of rum and no barrels are left: runaway!
|
|
|
|
|
|
debug = True
|
|
|
|
|
|
@@ -222,8 +223,8 @@ class Grid(Base):
|
|
|
|
|
|
elif type_ is Cannonball:
|
|
|
self.cannonballs.append(e)
|
|
|
- if e.pos not in self.threat or self.threat[e.pos] > e.countdown:
|
|
|
- self.threat = {e.pos: e.countdown}
|
|
|
+ if not e.pos in self.threat or e.countdown < self.threat[e.pos]:
|
|
|
+ self.threat[e.pos] = e.countdown
|
|
|
|
|
|
for s in self.owned_ships:
|
|
|
s.allies = [other for other in self.owned_ships if other is not s]
|
|
|
@@ -336,6 +337,9 @@ class Grid(Base):
|
|
|
for c, proba in next_positions[1].items():
|
|
|
if proba >= 20:
|
|
|
ship._moving_costs[c] = ship._moving_costs.get(c, 0) + 20 * proba
|
|
|
+ if ship.owned and not other.owned and other.behind in ship._moving_costs:
|
|
|
+ # the other ship could mine
|
|
|
+ ship._moving_costs[other.behind] += 100
|
|
|
|
|
|
def shooting_spot(self, ship, target, current=None):
|
|
|
shooting_spots = Queue()
|
|
|
@@ -542,7 +546,7 @@ class Grid(Base):
|
|
|
return result
|
|
|
|
|
|
# pathfinding
|
|
|
- def path(self, start, start_d, target, moving_costs={}, inertia=0, incl_start=False, limit=10000):
|
|
|
+ def path(self, start, start_d, target, moving_costs={}, inertia=None, incl_start=False, limit=10000):
|
|
|
nodes = Queue()
|
|
|
break_on, iteration = limit, 0
|
|
|
broken = False
|
|
|
@@ -558,6 +562,7 @@ class Grid(Base):
|
|
|
origin.orientation = start_d
|
|
|
|
|
|
nodes.put(origin, 0)
|
|
|
+
|
|
|
neighbors = []
|
|
|
|
|
|
while nodes:
|
|
|
@@ -589,18 +594,19 @@ class Grid(Base):
|
|
|
continue
|
|
|
|
|
|
d = Grid.direction_to(*current, x, y)
|
|
|
- if current == start and inertia == 0 and d != current.orientation:
|
|
|
+ if inertia == 0:
|
|
|
# special: if started with speed 0, first move will require a speed_up,
|
|
|
# making impossible a direction change at first node
|
|
|
- continue
|
|
|
+ if current.parent and current.parent == start and d != current.orientation:
|
|
|
+ continue
|
|
|
|
|
|
diff = abs(Grid.diff_directions(current.orientation, d))
|
|
|
if diff > 1:
|
|
|
# change direction one degree at a time
|
|
|
+ if current == (11,9) and (x, y) == (12,10): log("d")
|
|
|
continue
|
|
|
|
|
|
- area = Ship.get_area(x, y, d)
|
|
|
- area = [area[0], area[2]]
|
|
|
+ area = Ship.get_area(x, y, d)[::2]
|
|
|
if diff:
|
|
|
inertial_area = Ship.get_area(x, y, current.orientation)
|
|
|
area += [inertial_area[0], inertial_area[2]]
|
|
|
@@ -609,8 +615,8 @@ class Grid(Base):
|
|
|
|
|
|
cost = current.cost + moving_cost + diff * 20
|
|
|
|
|
|
- if (x, y) == start and d == start_d:
|
|
|
- # prefer to go right at start (if not speed)
|
|
|
+ if (x, y) == start and inertia == 0 and d == start_d:
|
|
|
+ # prefer to go right at start (if no speed)
|
|
|
cost -= 10
|
|
|
|
|
|
priority = cost + 10 * Grid.manhattan((x, y), target)
|
|
|
@@ -744,6 +750,7 @@ class Ship(Entity):
|
|
|
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, 1))
|
|
|
self.back_right = Grid.next_cell(*self.stern, Grid.add_directions(self.orientation, -1))
|
|
|
+ self.behind = Grid.next_cell(*self.stern, Grid.add_directions(self.orientation, 3))
|
|
|
|
|
|
self._can_move = {}
|
|
|
|
|
|
@@ -921,6 +928,13 @@ class Ship(Entity):
|
|
|
for move in available_moves:
|
|
|
|
|
|
new_area = self.area_after_moving(move)
|
|
|
+
|
|
|
+ # takes inertia in account
|
|
|
+ if move == Ship.SPEED_UP or self.speed and move == None:
|
|
|
+ for c in self.get_area(*Grid.next_cell(*new_area[1], self.orientation, self.speed + int(move == Ship.SPEED_UP)), self.orientation):
|
|
|
+ if not c in new_area:
|
|
|
+ new_area.append(c)
|
|
|
+
|
|
|
r = 0
|
|
|
|
|
|
for i, c in enumerate(new_area):
|
|
|
@@ -929,7 +943,9 @@ class Ship(Entity):
|
|
|
if mc >= 1000 and (c in grid or i == 1): # special: extra-grid cells are not consider as collisions since a part of the ship can go there
|
|
|
countdown = grid.threat.get(c, 0)
|
|
|
if countdown > 1 and mc < 2000:
|
|
|
+ # cannonball will hit there after next turn
|
|
|
r += 100
|
|
|
+
|
|
|
else:
|
|
|
if blocked and move in (Ship.SLOW_DOWN, None, Ship.SPEED_UP):
|
|
|
r = 1000
|
|
|
@@ -939,11 +955,6 @@ class Ship(Entity):
|
|
|
else:
|
|
|
r += 250
|
|
|
|
|
|
- if r:
|
|
|
- if self.speed and move == Ship.SPEED_UP or self.speed == self.MAX_SPEED and move != Ship.SLOW_DOWN:
|
|
|
- # danger: better slow down
|
|
|
- r += 20
|
|
|
-
|
|
|
if not r:
|
|
|
if move == planned:
|
|
|
r = -1
|
|
|
@@ -1265,6 +1276,7 @@ while True:
|
|
|
|
|
|
if ship.objective:
|
|
|
ship.goto = ship.objective.target.pos
|
|
|
+
|
|
|
elif ship.target_ennemy:
|
|
|
if all(s.stock < ship.stock for s in grid.ships if not s is ship):
|
|
|
log("Best stock: runaway!")
|
|
|
@@ -1284,7 +1296,6 @@ while True:
|
|
|
inertia=ship.speed,
|
|
|
limit=(max_it - it_consumed))
|
|
|
it_consumed += its
|
|
|
- log(ship.path)
|
|
|
|
|
|
if ship.objective and ship.path and ship.path[-1] == ship.goto:
|
|
|
while ship.objectives and len(ship.path) < 15:
|
|
|
@@ -1298,13 +1309,11 @@ while True:
|
|
|
new_path, its = grid.path(pos, d,
|
|
|
current_obj.target.pos,
|
|
|
moving_costs=ship._moving_costs,
|
|
|
- inertia=None,
|
|
|
limit=(max_it - it_consumed))
|
|
|
|
|
|
it_consumed += its
|
|
|
|
|
|
if new_path and new_path[-1] == current_obj.target.pos:
|
|
|
- log(new_path)
|
|
|
ship.path += new_path
|
|
|
else:
|
|
|
break
|
|
|
@@ -1369,6 +1378,8 @@ while True:
|
|
|
# * remove cache on 'next_pos_proba'
|
|
|
# * improve the fire_at_will algo
|
|
|
# * takes all ennemies in account to find the best shot
|
|
|
-# * add the runaway behaviour
|
|
|
-# * fix the can_go_fwd method
|
|
|
-# * better path computing for the next objectives (with inertia which can be None)
|
|
|
+
|
|
|
+# 2019-04-19
|
|
|
+# * path(): fix the special speed-up-inertia when start whith speed 0
|
|
|
+# * fix the grid.threat update
|
|
|
+# * add a moving cost at the prow of enemy ships to avoid a possible mine
|