Take the nearest planet that can be won, aiming ahead of orbiting ones
Browse filesChecks
play
Details
+43 −0 routes/swarm/main.py added View file
| @@ -0,0 +1,43 @@ | ||
| 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 | |
