| 1 | """A field bot written here: each planet sends just enough ships to take the nearest planet it can win, aiming where an |
| 2 | orbiting target will be when the fleet arrives.""" |
| 3 | import math |
| 4 | |
| 5 | CENTER = 50.0 |
| 6 | |
| 7 | |
| 8 | def speed(ships, top=6.0): |
| 9 | return 1.0 + (top - 1.0) * (math.log(max(ships, 1)) / math.log(1000)) ** 1.5 |
| 10 | |
| 11 | |
| 12 | def where(p, init, w, t): |
| 13 | """An orbiting planet's position t turns from now (static planets stay put).""" |
| 14 | if init is None: |
| 15 | return p[2], p[3] |
| 16 | r = math.hypot(init[2] - CENTER, init[3] - CENTER) |
| 17 | if r + p[4] >= 50: |
| 18 | return p[2], p[3] |
| 19 | a = math.atan2(p[3] - CENTER, p[2] - CENTER) + w * t |
| 20 | return CENTER + r * math.cos(a), CENTER + r * math.sin(a) |
| 21 | |
| 22 | |
| 23 | def agent(obs, config=None): |
| 24 | me, moves = obs['player'], [] |
| 25 | init = {p[0]: p for p in obs.get('initial_planets', [])} |
| 26 | w = obs.get('angular_velocity', 0.0) |
| 27 | mine = [p for p in obs['planets'] if p[1] == me] |
| 28 | for p in mine: |
| 29 | best = None |
| 30 | for q in obs['planets']: |
| 31 | if q[1] == me: |
| 32 | continue |
| 33 | need = q[5] + 1 + (q[6] * 10 if q[1] >= 0 else 0) |
| 34 | if p[5] - 5 < need: |
| 35 | continue |
| 36 | d = math.hypot(q[2] - p[2], q[3] - p[3]) |
| 37 | if best is None or d < best[0]: |
| 38 | best = (d, q, need) |
| 39 | if best: |
| 40 | d, q, need = best |
| 41 | x, y = where(q, init.get(q[0]), w, d / speed(need)) |
| 42 | moves.append([p[0], math.atan2(y - p[3], x - p[2]), int(need)]) |
| 43 | return moves |