Пример #1
0
 def getdensity(self,pos,dist,inspire = False):
     total = 0
     for x in range(pos.x - dist, pos.x + dist + 1):
         for y in range(pos.y - dist, pos.y + dist + 1):
             temp = self.normalize(hlt.Position(x, y))
             total += self[temp].halite_amount
     return total / (dist * dist * 4)
Пример #2
0
def get_maxPosition(ship, hlt_map, planned_position, game):
    max_value = [0.0, 1.0, 2.0]
    max_key = {0.0: (0, 0), 1.0: (0, 0), 2.0: (0, 0)}
    for k in hlt_map:
        min_max = min(max_value)
        if k not in planned_position and hlt_map[k] > min_max:
            if hlt_map[k] not in max_key:
                max_key[hlt_map[k]] = k
                min_idx = max_value.index(min(max_value))
                max_value[min_idx] = hlt_map[k]
            else:
                c = 0.01
                while hlt_map[k] + c in max_key:
                    c += c
                max_key[hlt_map[k] + c] = k
                min_idx = max_value.index(min(max_value))
                max_value[min_idx] = hlt_map[k] + c
            del max_key[min_max]

    max_reward = 10000
    desired_position = ship.position

    for key, position in max_key.items():
        p = hlt.Position(position[0], position[1])
        nav = game.game_map.aStar_plan(ship.position, p)
        home_nav = game.game_map.aStar_plan(p, me.shipyard.position)
        position_cost = (nav['cost'] + home_nav['cost']) / hlt_map[position]
        if position_cost < max_reward:
            max_reward = position_cost
            desired_position = p
    return desired_position
Пример #3
0
    def get_area_arr(self):
        r = self.game_map.width % self.len
        q = int((self.game_map.width - r) /
                self.len)  # q = num of area sections per dimension

        len_arr = []
        idx = 0
        n = 0
        for i in range(q):
            if i < r:
                len = self.len + 1
            else:
                len = self.len
            len_arr.append(len)
            if i != 0:
                idx += len
            self.idx_arr.append(idx)
            n += 1

        for i in range(n - 1):
            i_arr = []
            for j in range(n - 1):
                centroid_x = math.floor(
                    (self.idx_arr[i] + self.idx_arr[i + 1]) / 2)
                centroid_y = math.floor(
                    (self.idx_arr[j] + self.idx_arr[j + 1]) / 2)
                centroid = hlt.Position(centroid_x, centroid_y)
                len = len_arr[i]
                area_ij = Area(centroid, len)
                self.area_stats(area_ij)
                #self.area_arr.append(area_ij)
                i_arr.append(area_ij)
                self.tot_hal += area_ij.hal
            self.area_arr.append(i_arr)
Пример #4
0
 def checked_positions():
     """Generator for positions to check for ennemies"""
     for base_position in chain([me.shipyard], me.get_dropoffs()):
         x_shipyard = base_position.position.x
         y_shipyard = base_position.position.y
         for x in range(-search_range, search_range):
             for y in range(-search_range, search_range):
                 yield hlt.Position(x=x_shipyard + x, y=y_shipyard + y)
Пример #5
0
def get_total_halite(game):
    halite = 0
    for x in range(game.game_map.width):
        for y in range(game.game_map.height):
            p = hlt.Position(x, y)
            halite += game.game_map[p].halite_amount

    return halite
Пример #6
0
def get_info(game_map, occ_arr, hlt_amt, me):
    for y in range(game_map.height):
        for x in range(game_map.width):
            this_cell = game_map[hlt.Position(x, y)]
            occ_arr[x, y] = this_cell.is_occupied
            hlt_amt[x, y] = this_cell.halite_amount
    for ship in me.get_ships():
        occ_arr[ship.position.x, ship.position.y] = 2
    return occ_arr, hlt_amt
Пример #7
0
 def log_density(self,dist):
     for row in self._cells:
         for cell in row:
             pos = cell.position
             total = 0
             for x in range(pos.x - dist, pos.x + dist + 1):
                 for y in range(pos.y - dist, pos.y + dist + 1):
                     temp = self.normalize(hlt.Position(x, y))
                     total += self[temp].halite_amount
Пример #8
0
 def area_stats(self, area):
     x1, y1, x2, y2 = area.boundaries
     area.hal = 0
     area.n_enemies = 0
     for i in range(x1, x2 + 1):
         for j in range(y1, y2 + 1):
             cell = self.game_map[hlt.Position(i, j)]
             area.hal += cell.halite_amount
             if cell.is_occupied and cell.ship.id is not self.my_id:
                 area.n_enemies += 1
Пример #9
0
        def spawn(yard):
            cost = self.constants.SHIP_COST

            if me.halite_amount >= cost:
                id = max(me._ships) + 1 if len(me._ships) else 0
                pos = hlt.Position(yard.position.x, yard.position.y)
                me._ships[id] = hlt.entity.Ship(me, id, pos, 0)
                gmap[yard].ship = me._ships[id]
                me.halite_amount -= cost
                return True

            return False
Пример #10
0
        def convert(ship):
            cell = gmap[ship]
            cost = self.constants.DROPOFF_COST

            if me.halite_amount >= cost and not cell.structure:
                id = max(me._dropoffs) + 1 if len(me._dropoffs) else 0
                pos = hlt.Position(ship.position.x, ship.position.y)
                me._dropoffs[id] = hlt.entity.Dropoff(me, id, pos)
                cell.structure = me._dropoffs[id]
                me.halite_amount -= cost
                delete(ship)
                return True

            return False
Пример #11
0
def assign_targets(game, gs):
    p_dist = list(range(-2, 3))
    map_values = {}

    for x in range(game.game_map.width):
        for y in range(game.game_map.height):
            p = hlt.Position(x, y)
            value = 0

            # for this position get the surrounding cells and add up the halite values
            for dx in p_dist:
                for dy in p_dist:
                    temp_p = hlt.Position(x + dx, y + dy)
                    p_n = game.game_map.normalize(temp_p)
                    value += game.game_map[p_n].halite_amount

            map_values[p] = value

    # now scale the values for each ship we want to assign
    max_dist = math.sqrt((game.game_map.width * game.game_map.width / 4) +
                         (game.game_map.height * game.game_map.height / 4))

    for g in gs:
        if game.me.has_ship(g.id):
            temp_map_vals = {}
            for pos, val in map_values.items():
                dist = game.game_map.calculate_distance(
                    game.me.get_ship(g.id).position, pos)
                d_value = 1 + ((dist / max_dist) * (GAP.DSCALE - 1))
                temp_map_vals[pos] = val / d_value

            # now sort and assign
            sorted_d = sorted(temp_map_vals.items(),
                              key=lambda x: x[1],
                              reverse=True)
            g.seek_pos = sorted_d[0][0]
            map_values.pop(g.seek_pos, None)
Пример #12
0
def get_targets(game, n):
    p_dist = [-1, 0, 1]
    map_values = {}

    for x in range(game.game_map.width):
        for y in range(game.game_map.height):
            p = hlt.Position(x, y)
            value = 0

            # for this position get the surrounding cells and add up the halite values
            for dx in p_dist:
                for dy in p_dist:
                    temp_p = hlt.Position(x + dx, y + dy)
                    p_n = game.game_map.normalize(temp_p)
                    value += game.game_map[p_n].halite_amount

            dist = game.game_map.calculate_distance(game.me.shipyard.position,
                                                    p)
            max_dist = math.sqrt(
                (game.game_map.width * game.game_map.width / 4) +
                (game.game_map.height * game.game_map.height / 4))

            d_max = 3
            d_value = 1 + ((dist / max_dist) * (d_max - 1))

            value = value / d_value

            map_values[p] = value

    # sort map_values and return the best n positions
    sorted_d = sorted(map_values.items(), key=lambda x: x[1], reverse=True)

    targets = []
    for i in range(n):
        targets.append(sorted_d[i][0])

    return targets
Пример #13
0
    def max_halite_within_distance(self, game_map, location, distance):
        max_halite_cell = location
        max_halite = 0
        for dx in range(-distance, distance + 1):
            for dy in range(-distance, distance + 1):
                loc = game_map.normalize(location + hlt.Position(dx, dy))
                if game_map.calculate_distance(location, loc) > distance:
                    continue

                # pick cell with max halite
                cell_halite = game_map[loc].halite_amount
                if cell_halite > max_halite:
                    max_halite_cell = loc
                    max_halite = cell_halite
        return max_halite_cell
Пример #14
0
def parse_replay_file(file_name, player_name):
    print("Load Replay: " + file_name)
    with open(file_name, 'rb') as f:
        data = json.loads(zstd.loads(f.read()).decode('utf-8'))

    print("Load Basic Information")
    player = [p for p in data['players'] if p['name'] == player_name][0]
    player_id = int(player['player_id'])
    my_shipyard = hlt.Shipyard(
        player_id, ARBITRARY_ID,
        hlt.Position(player['factory_location']['x'],
                     player['factory_location']['y']))
    other_shipyards = [
        hlt.Shipyard(
            p['player_id'], ARBITRARY_ID,
            hlt.Position(p['factory_location']['x'],
                         p['factory_location']['y'])) for p in data['players']
        if int(p['player_id']) != player_id
    ]
    width = data['production_map']['width']
    height = data['production_map']['height']

    print("Load Cell Information")
    first_cells = []
    for x in range(len(data['production_map']['grid'])):
        row = []
        for y in range(len(data['production_map']['grid'][x])):
            row += [
                hlt.MapCell(hlt.Position(x, y),
                            data['production_map']['grid'][x][y]['energy'])
            ]
        first_cells.append(row)
    frames = []
    for f in data['full_frames']:
        prev_cells = first_cells if len(frames) == 0 else frames[-1]._cells
        new_cells = copy.deepcopy(prev_cells)
        for c in f['cells']:
            new_cells[c['y']][c['x']].halite_amount = c['production']
        frames.append(hlt.GameMap(new_cells, width, height))

    print("Load Player Ships")
    moves = [{} if str(player_id) not in f['moves'] else {
        m['id']: m['direction']
        for m in f['moves'][str(player_id)] if m['type'] == "m"
    } for f in data['full_frames']]
    ships = [{} if str(player_id) not in f['entities'] else {
        int(sid): hlt.Ship(player_id, int(sid),
                           hlt.Position(ship['x'], ship['y']), ship['energy'])
        for sid, ship in f['entities'][str(player_id)].items()
    } for f in data['full_frames']]

    print("Load Other Player Ships")
    other_ships = [{
        int(sid): hlt.Ship(int(pid), int(sid),
                           hlt.Position(ship['x'], ship['y']), ship['energy'])
        for pid, p in f['entities'].items() if int(pid) != player_id
        for sid, ship in p.items()
    } for f in data['full_frames']]

    print("Load Droppoff Information")
    first_my_dropoffs = [my_shipyard]
    first_them_dropoffs = other_shipyards
    my_dropoffs = []
    them_dropoffs = []
    for f in data['full_frames']:
        new_my_dropoffs = copy.deepcopy(
            first_my_dropoffs if len(my_dropoffs) == 0 else my_dropoffs[-1])
        new_them_dropoffs = copy.deepcopy(first_them_dropoffs if len(
            them_dropoffs) == 0 else them_dropoffs[-1])
        for e in f['events']:
            if e['type'] == 'construct':
                if int(e['owner_id']) == player_id:
                    new_my_dropoffs.append(
                        hlt.Dropoff(
                            player_id, ARBITRARY_ID,
                            hlt.Position(e['location']['x'],
                                         e['location']['y'])))
                else:
                    new_them_dropoffs.append(
                        hlt.Dropoff(
                            e['owner_id'], ARBITRARY_ID,
                            hlt.Position(e['location']['x'],
                                         e['location']['y'])))
        my_dropoffs.append(new_my_dropoffs)
        them_dropoffs.append(new_them_dropoffs)
    return list(
        zip(frames, moves, ships, other_ships, my_dropoffs, them_dropoffs))
Пример #15
0
DROP_TURNS = 200

# fitted (see ols and dropoff count script)
DROP_ALPHA_BETA = {
    32: {2: (-1.16, 1.28e-05), 4: (-0.65, 9.25e-06)},
    40: {2: (-1.87, 1.38e-05), 4: (-1.55, 1.23e-05)},
    48: {2: (-1.77, 1.45e-05), 4: (0.95, 2.56e-06)},
    56: {2: (1.33, 6.06e-06), 4: (-3.01, 1.26e-05)},
    64: {2: (-2.26, 1.07e-05), 4: (-3.91, 1.09e-05)},
}[width][num_players]

if not warmup:
    INITIAL_HALITE = 0
    for x in range(width):
        for y in range(width):
            position = hlt.Position(x, y)
            INITIAL_HALITE += game_map[position].halite_amount
    MAX_DROPS = np.floor(DROP_ALPHA_BETA[0] + INITIAL_HALITE * DROP_ALPHA_BETA[1])


# median last spawn turn from teccles games
SPAWN_TURNS = {
    32: {2: 300, 4: 145},
    40: {2: 318, 4: 197},
    48: {2: 336, 4: 204},
    56: {2: 369, 4: 223},
    64: {2: 375, 4: 291},
}[width][num_players]

returning_ships = set()
forced_return_ships = set()
Пример #16
0
def surrounding_ocean(ship, data_frame, area):
    # Ultimate list that will house the data of positionals around a ship.  This is with the ship at origin.  Consider this a "mask."
    # Once we have the area we need to convert back to the map positionals to query status / halite amount.
    gameMap = data_frame[0]
    ship_keys = list(data_frame[2].keys())
    friendly_ships = data_frame[2]
    friendly_structures = list(data_frame[4])
    enemy_ship_keys = list(data_frame[3].keys())
    enemy_ship_data = data_frame[3]
    enemy_struc_data = data_frame[5]

    enemy_ships = []
    for i in enemy_ship_keys:
        enemy_ships.append(enemy_ship_data[i].position)
    enemy_structures = []
    for i in enemy_struc_data:
        enemy_structures.append(i.position)

    all_ships = []
    for i in ship_keys:
        all_ships.append(friendly_ships[i].position)

    all_structures = []
    for i in friendly_structures:
        all_structures.append(i.position)

    map_box = []  # converted "map cell" positions
    for yval in range(-1 * area, area + 1):
        row = []
        for xval in range(-1 * area, area + 1):
            cell = gameMap[hlt.Position(ship.position.y, ship.position.x) +
                           hlt.Position(xval, yval)]

            if cell.position in all_structures:
                structure_friend_foe = 1
            elif cell.position in enemy_structures:
                structure_friend_foe = -1
            else:
                structure_friend_foe = 0

            if cell.position in all_ships:
                ship_friend_foe = 1
                friendly_ship = all_ships.index(cell.position)
                friendly_ship = ship_keys[friendly_ship]
                ship_halite = friendly_ships[friendly_ship].halite_amount
                ships = round(ship_friend_foe * ship_halite / MAX_HALITE, 3)
                if ships > 1.000:
                    ships = 1.000
            elif cell.position in enemy_ships:
                ship_friend_foe = -1
                enemy_ship = enemy_ships.index(cell.position)
                enemy_ship = enemy_ship_keys[enemy_ship]
                ship_halite = enemy_ship_data[enemy_ship].halite_amount
                ships = round(ship_friend_foe * ship_halite / MAX_HALITE, 3)
                if ships > 1.000:
                    ships = 1.000
            else:
                ship_friend_foe = 0
                ships = 0

            current_halite = round(cell.halite_amount / MAX_HALITE, 3)
            # logic to ensure that the value of halite never is greater than 1
            if current_halite > 1:
                current_halite = 1.000

            map_values = (current_halite, ships, structure_friend_foe)
            row.append(map_values)
        map_box.append(row)

    return map_box
Пример #17
0
#!/usr/bin/env python3
import hlt
from hlt import constants
from hlt.positionals import Direction
import random
import logging

""" <<<Game Begin>>> """
game = hlt.Game()
all_cells_collection = [hlt.Position(i, y) for i in range(game.game_map.width) for y in range(game.game_map.height)]
game.ready("simple_rad_v1")
logging.info("Successfully created bot! My Player ID is {}.".format(game.my_id))
""" <<<Game Loop>>> """

while True:
    game.update_frame()
    me = game.me
    game_map = game.game_map
    halite_map = {cell: game_map[cell].halite_amount for cell in all_cells_collection}
    # logging.info("{}.".format(all_cells_collection))
    # logging.info("{}.".format(halite_map))

    command_queue = []
    direction_order = [Direction.North, Direction.South, Direction.East, Direction.West, Direction.Still]
    for ship in me.get_ships():

        position_options = ship.position.get_surrounding_cardinals() + [ship.position]

        position_dict = {}
        halite_dict = {}
Пример #18
0

while U:
    Q.update_frame()
    me = Q.me
    u = Q.game_map
    q = F
    g = []
    for M in V(0, u.height, 8):
        for C in V(0, u.width, 8):
            B = 0
            K = (C, M)
            o = 0
            for y in V(M, M + 8):
                for x in V(C, C + 8):
                    L = u[hlt.Position(x, y)].halite_amount
                    B += L
                    if L > o:
                        K = (x, y)
                        o = L
            if B > 3000:
                g.append((K[0], K[1], B / (1 + u.calculate_distance(
                    hlt.Position(C + 4, M + 4), me.shipyard.position))))
    T = G(g, key=lambda x: x[2])
    h = []
    p = [me.shipyard.position] + [W.position for W in me.get_dropoffs()]
    for e in me.get_ships():
        if e.position in p:
            plans[e.id] = c
        if plans.get(e.id) == 'return' or e.halite_amount > 700:
            plans[e.id] = 'return'
Пример #19
0
                    ship.position, me.shipyard.position):
            ship_status[ship.id] = "end of game"
        elif ship.halite_amount >= constants.MAX_HALITE * 0.70:
            ship_status[ship.id] = "returning"
            if ship.id in mission:
                del mission[ship.id]

        if ship_status[ship.id] == "exploring":
            if ship.id not in mission:
                maxP = get_maxPosition(ship, hlt_map, planned_position, game)
                move = game_map.aStar_navigate(ship, maxP)
                command_queue.append(ship.move(move))
                planned_position.append((maxP.x, maxP.y))
                mission[ship.id] = (maxP.x, maxP.y)
            else:
                maxP = hlt.Position(mission[ship.id][0], mission[ship.id][1])
                move = game_map.aStar_navigate(ship, maxP)
                command_queue.append(ship.move(move))
                planned_position.append(mission[ship.id])
                if game_map[maxP].halite_amount <= 15:
                    del mission[ship.id]
            logging.info(
                "Ship {} has {} halite and is {} to {} from {} by moving {}.".
                format(ship.id, ship.halite_amount, ship_status[ship.id], maxP,
                       ship.position, move))

        elif ship_status[ship.id] == "returning":
            if ship.position == me.shipyard.position:
                ship_status[ship.id] = "exploring"

            # elif me.halite_amount > constants.DROPOFF_COST:
v.ready("PriorityCollector")
p("Successfully created bot! My Player ID is {}.".format(v.my_id))
b={}
while f:
	v.update_frame()
	me=v.me
	u=v.game_map
	F=[]
	for j in A(0,u.height,8):
		for R in A(0,u.width,8):
			M=0
			i=(R,j)
			W=0
			for y in A(j,j+8):
				for x in A(R,R+8):
					L=u[hlt.Position(x,y)].halite_amount
					M+=L
					if L>W:
						i=(x,y)
						W=L
			if M>3000:
				F.append((i[0],i[1],M/(1+u.calculate_distance(hlt.Position(R+4,j+4),me.shipyard.position))))
	O=a(F,key=lambda x:x[2])
	G=[]
	for m in me.get_ships():
		if m.position==me.shipyard.position:
			b[m.id]=w
		if b.get(m.id)=='return' or m.halite_amount>700:
			b[m.id]='return'
			x=me.shipyard.position
			V=u.naive_navigate(m,x)
Пример #21
0
        if (me.halite_amount + ship.halite_amount
            ) > y2 * constants.DROPOFF_COST and game_map.calculate_distance(
                ship.position,
                me.shipyard.position) >= (4 / 3) * r and not built_drop:
            built_drop = True
            command_queue.append(ship.make_dropoff())
            logging.info("Ship {} is being turned into a dropoff.".format(
                ship.id))
        elif ship_status[ship.id] == "exploring":
            if ship.id not in mission:
                maxP = get_maxPosition(ship, hlt_map, planned_position, game)
                # if game_map[maxP].halite_amount > y*game_map[ship.position].halite_amount:
                move = game_map.aStar_navigate(ship, maxP)

                next_ = ship.position + hlt.Position(move[0], move[1])
                next_location[ship.id] = (next_.x, next_.y)
                if game.turn_number > 1 and ship.id in current_location:
                    prev_location[ship.id] = current_location[ship.id]
                    if prev_location[ship.id] == next_location[ship.id]:
                        move = (0, 0)
                current_location[ship.id] = (ship.position.x, ship.position.y)

                command_queue.append(ship.move(move))
                planned_position.append((maxP.x, maxP.y))
                mission[ship.id] = (maxP.x, maxP.y)

            else:
                maxP = hlt.Position(mission[ship.id][0], mission[ship.id][1])
                move = game_map.aStar_navigate(ship, maxP)
                command_queue.append(ship.move(move))
Пример #22
0
    def next_state(self, state, action):
        state = copy.deepcopy(state)
        gmap = state.game_map

        def idx(entity):
            return entity.position.y, entity.position.x

        def delete(ship):
            gmap[ship].ship = None
            ship.owner._ships.pop(ship.id)

        def mine(ship, inspired=False):
            if inspired:
                ratio = self.constants.INSPIRED_EXTRACT_RATIO
            else:
                ratio = self.constants.EXTRACT_RATIO

            cell = gmap[ship]
            gained = extracted = math.ceil(cell.halite_amount / ratio)

            if extracted == 0 and cell.halite_amount > 0:
                gained = extracted = cell.halite_amount

            if extracted + ship.halite_amount > self.constants.MAX_HALITE:
                extracted = self.constants.MAX_HALITE - ship.halite_amount

            if inspired:
                gained += gained * self.constants.INSPIRED_BONUS_MULTIPLIER

            if self.constants.MAX_HALITE - ship.halite_amount < gained:
                gained = self.constants.MAX_HALITE - ship.halite_amount

            ship.halite_amount += gained
            cell.halite_amount -= extracted

        def move(ship, direction, inspired=False):
            if inspired:
                ratio = self.constants.INSPIRED_MOVE_COST_RATIO
            else:
                ratio = self.constants.MOVE_COST_RATIO

            cell = gmap[ship]
            cost = round(cell.halite_amount / ratio)

            if ship.halite_amount >= cost:
                ship.position = gmap.normalize(ship.position + direction)
                cell.ship, gmap[ship].ship = None, ship
                ship.halite_amount -= cost
                return True

            return False

        def convert(ship):
            cell = gmap[ship]
            cost = self.constants.DROPOFF_COST

            if me.halite_amount >= cost and not cell.structure:
                id = max(me._dropoffs) + 1 if len(me._dropoffs) else 0
                pos = hlt.Position(ship.position.x, ship.position.y)
                me._dropoffs[id] = hlt.entity.Dropoff(me, id, pos)
                cell.structure = me._dropoffs[id]
                me.halite_amount -= cost
                delete(ship)
                return True

            return False

        def spawn(yard):
            cost = self.constants.SHIP_COST

            if me.halite_amount >= cost:
                id = max(me._ships) + 1 if len(me._ships) else 0
                pos = hlt.Position(yard.position.x, yard.position.y)
                me._ships[id] = hlt.entity.Ship(me, id, pos, 0)
                gmap[yard].ship = me._ships[id]
                me.halite_amount -= cost
                return True

            return False

        def is_inspired(ship):
            enemies = 0
            open, closed = [], set()
            open.append((0, ship.position.y, ship.position.x))

            while len(open):
                dist, j, i = open[0]
                cell = gmap._cells[j][i]
                closed.add((j, i))
                open = open[1:]

                if cell.ship and cell.ship.owner is not ship.owner:
                    enemies += 1
                    if enemies >= self.constants.INSPIRATION_SHIP_COUNT:
                        return True

                if dist < self.constants.INSPIRATION_RADIUS:
                    for dj, di in hlt.Direction.get_all_cardinals():
                        _j, _i = (j + dj) % gmap.height, (i + di) % gmap.width
                        if (_j, _i) not in closed:
                            open.append((dist + 1, _j, _i))

            return False

        # ==== MY ACTIONS ==== #

        me = state.me

        for ship in me.get_ships():
            a = action[idx(ship)]

            if a < 4:  # move
                mv = hlt.Direction.get_all_cardinals()[a]
                if move(ship, hlt.Position(*mv), inspired=is_inspired(ship)):
                    continue

            if a == 4:  # make dropoff
                if convert(ship):
                    continue

            mine(ship, inspired=is_inspired(ship))  # stay still

        if action[idx(me.shipyard)] == 6:  # new ship
            spawn(me.shipyard)

        # ==== ENEMIES ==== #

        for id in state.players:
            if id != me.id:
                for ship in state.players[id].get_ships():
                    mine(ship, inspired=is_inspired(ship))  # stay still

        # ==== COLLISIONS ==== #

        collisions = {}
        all_ships = (s for p in state.players.values() for s in p.get_ships())

        for ship in all_ships:  # detect
            key, other = idx(ship), gmap[ship].ship

            if other and other is not ship:
                if key in collisions:
                    collisions[key].append(ship)
                else:
                    collisions[key] = [other, ship]

        for (j, i), collision in collisions.items():  # resolve
            cell = gmap._cells[j][i]
            h = cell.halite_amount + sum(s.halite_amount for s in collision)
            cell.halite_amount = min(h, hlt.constants.MAX_HALITE)

            for ship in collision:
                delete(ship)

        # ==== DROP HALITE ==== #

        for dropoff in me.get_dropoffs() + [me.shipyard]:  # get halite
            cell = gmap[dropoff]
            me.halite_amount += cell.halite_amount
            cell.halite_amount = 0

            if cell.ship:
                me.halite_amount += cell.ship.halite_amount
                cell.ship.halite_amount = 0

        return state