|
|
@@ -8,9 +8,16 @@ import time
|
|
|
|
|
|
|
|
|
# TODO:
|
|
|
-# * improve the probability next pos
|
|
|
# * find a way to change direction without slowing down if possible
|
|
|
# * avoid getting blocked by a side-by-side with an ennemy
|
|
|
+# * Fix: do not target a barrel that an ennemy is going to take
|
|
|
+# * Try to interger extra steps into the path algo, instead of adding independents paths
|
|
|
+# Check if cannonballs with countdown 0 can be ignored in the plan_next_move algo ?
|
|
|
+# Fix: do not shoot a mine if we are close to it
|
|
|
+# Fix: if every move leads to collision, avoid those whop hit the center of the ship
|
|
|
+
|
|
|
+# Notes:
|
|
|
+# * Fix: Do not target a barrel that is in the dead angle -> barrels are estimated from the prow
|
|
|
|
|
|
debug = True
|
|
|
|
|
|
@@ -102,7 +109,10 @@ class BaseObjective(Base):
|
|
|
|
|
|
class GetBarrel(BaseObjective):
|
|
|
def _compute_interest(self):
|
|
|
- self.interest = 6 * self.distance + 12 * self.alignment + 3 * self.target.dispersal + self.target.mine_threat ** 2 - 24 * self.target.ennemy_near
|
|
|
+ self.interest = 6 * self.distance + 9 * self.alignment + 3 * self.target.dispersal + self.target.mine_threat * 2 + 12 * self.target.ennemy_near
|
|
|
+ if self.distance <= 2 and self.alignment > 1:
|
|
|
+ # dead angle
|
|
|
+ self.interest -= 18
|
|
|
|
|
|
class Attack(BaseObjective):
|
|
|
def _compute_interest(self):
|
|
|
@@ -235,7 +245,7 @@ class Grid(Base):
|
|
|
|
|
|
for b in self.barrels:
|
|
|
obj = GetBarrel(b)
|
|
|
- obj.eval(s.pos, s.orientation)
|
|
|
+ obj.eval(s.prow, s.orientation)
|
|
|
s.objectives.put(obj)
|
|
|
|
|
|
for e in self.ennemy_ships:
|
|
|
@@ -301,7 +311,7 @@ class Grid(Base):
|
|
|
|
|
|
next_positions = other.next_pos_proba()
|
|
|
for c, proba in next_positions[1].items():
|
|
|
- ship._moving_costs[c] = ship._moving_costs.get(c, 0) + 40 * proba
|
|
|
+ ship._moving_costs[c] = ship._moving_costs.get(c, 0) + 10 * proba
|
|
|
|
|
|
def shooting_spot(self, ship, target):
|
|
|
shooting_spots = Queue()
|
|
|
@@ -478,13 +488,11 @@ class Grid(Base):
|
|
|
break_on, iteration = limit, 0
|
|
|
broken = False
|
|
|
|
|
|
- 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
|
|
|
@@ -499,10 +507,10 @@ class Grid(Base):
|
|
|
path = []
|
|
|
previous = current
|
|
|
while previous:
|
|
|
- if previous != origin or incl_start:
|
|
|
+ if previous != start or incl_start:
|
|
|
path.insert(0, previous)
|
|
|
previous = previous.parent
|
|
|
- return inertia_path + path, iteration
|
|
|
+ return path, iteration
|
|
|
|
|
|
neighbors = self.neighbors(*current)
|
|
|
|
|
|
@@ -534,9 +542,9 @@ class Grid(Base):
|
|
|
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)
|
|
|
+
|
|
|
node = PathNode(x, y, current)
|
|
|
node.cost = cost
|
|
|
node.orientation = d
|
|
|
@@ -871,14 +879,12 @@ class Ship(Entity):
|
|
|
if diff and next_flag == 0:
|
|
|
# start, with a direction change
|
|
|
if diff > 0:
|
|
|
- if self.can_turn_left():
|
|
|
- return Ship.TURN_LEFT
|
|
|
+ return Ship.TURN_LEFT
|
|
|
elif diff < 0:
|
|
|
- if self.can_turn_right():
|
|
|
- return Ship.TURN_RIGHT
|
|
|
+ return Ship.TURN_RIGHT
|
|
|
|
|
|
# start straight
|
|
|
- if self.can_move_fwd():
|
|
|
+ else:
|
|
|
return Ship.SPEED_UP
|
|
|
|
|
|
elif self.speed == self.MAX_SPEED:
|
|
|
@@ -930,10 +936,11 @@ class Ship(Entity):
|
|
|
return False
|
|
|
|
|
|
avoid = []
|
|
|
- for ally in self.allies:
|
|
|
- avoid += ally.next_area
|
|
|
+ for ship in grid.owned_ships:
|
|
|
+ avoid += ship.next_area
|
|
|
|
|
|
next_positions = target.next_pos_proba(4)
|
|
|
+ barrels = [b.pos for b in grid.barrels if not any(Grid.manhattan(ally.pos, b.pos) <= Grid.manhattan(target.pos, b.pos) for ally in self.allies)]
|
|
|
|
|
|
for t, probas in next_positions.items():
|
|
|
|
|
|
@@ -942,16 +949,16 @@ class Ship(Entity):
|
|
|
for c, proba in probas.items():
|
|
|
if c in grid.next_to_mine:
|
|
|
mpos = grid.next_to_mine[c].pos
|
|
|
+ if Grid.manhattan(self.next_pos, mpos) <= 2:
|
|
|
+ continue
|
|
|
mines_next[mpos] = mines_next.get(mpos, 1) + proba
|
|
|
probas.update(mines_next)
|
|
|
-
|
|
|
- barrels = [b.pos for b in grid.barrels]
|
|
|
+
|
|
|
for c in probas:
|
|
|
if c in barrels:
|
|
|
probas[c] += 20
|
|
|
|
|
|
shots = sorted(probas.items(), key=lambda x: x[1], reverse=True)
|
|
|
- log(t, shots)
|
|
|
|
|
|
for c, proba in shots:
|
|
|
if c in avoid:
|
|
|
@@ -1090,7 +1097,7 @@ while True:
|
|
|
# log(f"Mines: {grid.mines}")
|
|
|
log(f"Cannonballs: {grid.cannonballs}")
|
|
|
|
|
|
- max_it = 12000 // len(grid.owned_ships)
|
|
|
+ max_it = 9000 // len(grid.owned_ships)
|
|
|
|
|
|
### Acquire
|
|
|
log("# Acquiring")
|
|
|
@@ -1116,6 +1123,8 @@ while True:
|
|
|
for ship in grid.owned_ships:
|
|
|
log(f"---- ship {ship.id} ---")
|
|
|
log(f"ship: {ship}")
|
|
|
+ log(f"obj: {ship.objective}; next: {ship.objectives_next}")
|
|
|
+ log(f"target: {ship.target_ennemy}")
|
|
|
|
|
|
it_consumed = 0
|
|
|
|
|
|
@@ -1127,6 +1136,8 @@ while True:
|
|
|
log("ERROR: No target")
|
|
|
continue
|
|
|
|
|
|
+ log(f"goto: {ship.goto}")
|
|
|
+
|
|
|
ship.path, its = grid.path(ship.pos,
|
|
|
ship.orientation,
|
|
|
ship.goto,
|
|
|
@@ -1157,10 +1168,7 @@ while True:
|
|
|
break
|
|
|
|
|
|
ship.plan_next_move()
|
|
|
-
|
|
|
- log(f"obj: {ship.objective}; next: {ship.objectives_next}")
|
|
|
- log(f"target: {ship.target_ennemy}")
|
|
|
- log(f"goto: {ship.goto}")
|
|
|
+
|
|
|
log(f"path: {ship.path}")
|
|
|
log(f"next_move: {Ship.COMMANDS[ship.next_move]}")
|
|
|
|