"""A field bot written here: each planet sends just enough ships to take the nearest planet it can win, aiming where an orbiting target will be when the fleet arrives.""" import math CENTER = 50.0 def speed(ships, top=6.0): return 1.0 + (top - 1.0) * (math.log(max(ships, 1)) / math.log(1000)) ** 1.5 def where(p, init, w, t): """An orbiting planet's position t turns from now (static planets stay put).""" if init is None: return p[2], p[3] r = math.hypot(init[2] - CENTER, init[3] - CENTER) if r + p[4] >= 50: return p[2], p[3] a = math.atan2(p[3] - CENTER, p[2] - CENTER) + w * t return CENTER + r * math.cos(a), CENTER + r * math.sin(a) def agent(obs, config=None): me, moves = obs['player'], [] init = {p[0]: p for p in obs.get('initial_planets', [])} w = obs.get('angular_velocity', 0.0) mine = [p for p in obs['planets'] if p[1] == me] for p in mine: best = None for q in obs['planets']: if q[1] == me: continue need = q[5] + 1 + (q[6] * 10 if q[1] >= 0 else 0) if p[5] - 5 < need: continue d = math.hypot(q[2] - p[2], q[3] - p[3]) if best is None or d < best[0]: best = (d, q, need) if best: d, q, need = best x, y = where(q, init.get(q[0]), w, d / speed(need)) moves.append([p[0], math.atan2(y - p[3], x - p[2]), int(need)]) return moves