Просмотр исходного кода

split planning and acting for moves

olinox 6 лет назад
Родитель
Сommit
9b58360c37
1 измененных файлов с 43 добавлено и 29 удалено
  1. 43 29
      carribean/script.py

+ 43 - 29
carribean/script.py

@@ -12,8 +12,6 @@ import time
 # * find a way to change direction without slowing down if possible
 # * avoid getting blocked by a side-by-side with an ennemy
 # * use a queue to choose the best shoot instead of a strict equality
-# * why do mines explode when turning around?
-# * improve next_pos_proba: eliminate next positions if not passables
 
 debug = True
 
@@ -279,7 +277,7 @@ class Grid(Base):
         for m in self.mines:
             base_costs[m.pos] += 1000
         for c in self.cannonballs:
-            base_costs[c.pos] += (100 + (6 - c.countdown) * 200)
+            base_costs[c.pos] += (200 + (6 - c.countdown) * 200)
         
         for ship in self.ships:
             ship._moving_costs = {}
@@ -568,13 +566,12 @@ class Ship(Entity):
     MAX_SPEED = 2
     SCOPE = 10
     
-    WAIT = 0
     SLOW_DOWN = 1
     SPEED_UP = 2
     TURN_LEFT = 3
     TURN_RIGHT = 4
-    MOVES = [WAIT, SPEED_UP, TURN_LEFT, TURN_RIGHT, SLOW_DOWN]
-    COMMANDS = {SLOW_DOWN: "SLOWER", SPEED_UP: "FASTER", TURN_LEFT: "PORT", TURN_RIGHT: "STARBOARD", WAIT: "WAIT", None: "NONE"}
+    MOVES = [None, SPEED_UP, TURN_LEFT, TURN_RIGHT, SLOW_DOWN]
+    COMMANDS = {SLOW_DOWN: "SLOWER", SPEED_UP: "FASTER", TURN_LEFT: "PORT", TURN_RIGHT: "STARBOARD", None: "NONE"}
     
     areas = {}
     
@@ -652,6 +649,7 @@ class Ship(Entity):
         
         self.next_cell = self.get_next_cell()
         self.next_pos = self.get_next_pos()
+        self.next_move = None
         self.next_area = Ship.get_area(*self.next_pos, self.orientation)
         
         self.front = Grid.next_cell(*self.prow, self.orientation)
@@ -664,8 +662,6 @@ class Ship(Entity):
         
         self._can_move = {}
         
-        self.mobility_zone = list(set(self.area + self.next_area))
-            
         if self.traject() != previous_traject:
             self.same_traject_since += 1
         else:
@@ -803,18 +799,18 @@ class Ship(Entity):
         new_pos = self.get_next_cell(new_speed)
         return self.get_area(*new_pos, new_orientation)
     
-    def move(self, path):
+    def plan_next_move(self):
         
-        if path:
-            planned = self._plan_move(path)
+        if self.path:
+            planned = self._follow_path(self.path)
             
-        if path is None:
+        if self.path is None:
             if self.can_move():
                 available = {}
                 
                 if self.can_move_fwd():
                     if self.speed:
-                        available[Ship.WAIT] = 0
+                        available[None] = 0
                     else:
                         available[Ship.SPEED_UP] = 0
                 if self.can_turn_left():
@@ -829,8 +825,9 @@ class Ship(Entity):
                 log(f"(!) broken: automove ({Ship.COMMANDS[planned]})")
             else:
                 log(f"(!) broken: can not move")
+                self.next_area = self.area
                 return False
-        elif not path:
+        elif not self.path:
             return False
         
         next_move = planned
@@ -838,7 +835,7 @@ class Ship(Entity):
         
         for move in available_moves:
             new_area = self.area_after_moving(move)
-            
+
             # 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):
                 log(f"/!\ Danger: planned move <{Ship.COMMANDS[move]}> would lead to collision")
@@ -848,20 +845,25 @@ class Ship(Entity):
         else:
             log("* No collision-free move was found, go to the initial one")
         
-        if next_move == Ship.SPEED_UP:
+        self.next_move = next_move
+        self.next_area = new_area
+        return True
+        
+        
+    def move(self):
+        if self.next_move == Ship.SPEED_UP:
             self.speed_up()
-        elif next_move == Ship.SLOW_DOWN:
+        elif self.next_move == Ship.SLOW_DOWN:
             self.slow_down()
-        elif next_move == Ship.TURN_LEFT:
+        elif self.next_move == Ship.TURN_LEFT:
             self.turn_left()
-        elif next_move == Ship.TURN_RIGHT:
+        elif self.next_move == Ship.TURN_RIGHT:
             self.turn_right()
         else:
             return False
-
         return True
 
-    def _plan_move(self, path):
+    def _follow_path(self, path):
         
         # flags represent direction changes or end of the path
         last_flag = len(path) - 1
@@ -919,15 +921,13 @@ class Ship(Entity):
     def fire_at_will(self, *args, **kwargs):
         return self._fire_at_will(*args, **kwargs)
            
-    def _fire_at_will(self, target, allies = []):
+    def _fire_at_will(self, target):
         if not self.can_fire():
             return False
         
         avoid = []
-        if not self in allies:
-            allies.append(self)
-        for ally in allies:
-            avoid += ally.mobility_zone
+        for ally in self.allies:
+            avoid += ally.next_area
         
         next_positions = target.guess_next_positions(4)
         for t, next_pos in next_positions.items():
@@ -960,6 +960,13 @@ class Ship(Entity):
     def can_fire(self):
         return self.last_fire is None or (current_turn - self.last_fire) >= 1
             
+    def mine_maybe(self):
+        if self.can_mine():
+            if not any(Grid.manhattan(self.pos, ally.pos) <= 5 for ally in self.allies):
+                self.mine()
+                return True
+        return False
+            
     # --- Basic commands
     def _act(self, cmd, *args):
         self.last_action = cmd
@@ -1063,7 +1070,7 @@ while True:
 #     log(f"Mines: {grid.mines}")
     log(f"Cannonballs: {grid.cannonballs}")
     
-    max_it = 6000 // len(grid.owned_ships)
+    max_it = 12000 // len(grid.owned_ships)
 
     ### Acquire
     log("# Acquiring")
@@ -1126,6 +1133,8 @@ while True:
                 else:
                     break
  
+        ship.plan_next_move()
+ 
     for ship in grid.owned_ships:
         log(f"---- ship {ship.id} ---")
         log(f"ship: {ship}")
@@ -1133,6 +1142,7 @@ while True:
         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]}")
         
     ### Process
     log("# Processing")
@@ -1143,11 +1153,15 @@ while True:
             log("No target: wait")
             ship.wait()
         
-        if ship.move(ship.path):
+        if ship.move():
             continue
         
         # no movement was required, can fire
-        if ship.fire_at_will(ship.target_ennemy.target, allies=grid.owned_ships):
+        if ship.fire_at_will(ship.target_ennemy.target):
+            continue
+        
+        # or mine
+        if ship.mine_maybe():
             continue
         
         log("ERROR: Did not act, wait")