ab473c6b68
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
55 lines
1.5 KiB
Nim
55 lines
1.5 KiB
Nim
## Per-enemy state table. Keyed by bot ID.
|
|
## Tank Royale: 0° = East.
|
|
|
|
import std/tables
|
|
import std/math
|
|
|
|
type
|
|
EnemyState* = object
|
|
id*: int
|
|
x*, y*: float
|
|
heading*: float ## degrees
|
|
speed*: float
|
|
energy*: float
|
|
lastSeenTick*: int
|
|
alive*: bool
|
|
|
|
EnemyTracker* = object
|
|
enemies*: Table[int, EnemyState]
|
|
|
|
proc update*(et: var EnemyTracker, botId: int, x, y, heading, speed, energy: float, tick: int) =
|
|
et.enemies[botId] = EnemyState(id: botId, x: x, y: y, heading: heading,
|
|
speed: speed, energy: energy,
|
|
lastSeenTick: tick, alive: true)
|
|
|
|
proc markDead*(et: var EnemyTracker, botId: int) =
|
|
if botId in et.enemies:
|
|
et.enemies[botId].alive = false
|
|
|
|
proc resetRound*(et: var EnemyTracker) =
|
|
et.enemies.clear()
|
|
|
|
proc getEnemy*(et: EnemyTracker, botId: int): EnemyState =
|
|
et.enemies[botId]
|
|
|
|
proc allAlive*(et: EnemyTracker): seq[EnemyState] =
|
|
for s in et.enemies.values:
|
|
if s.alive: result.add(s)
|
|
|
|
proc closestTo*(et: EnemyTracker, x, y: float): EnemyState =
|
|
var bestDist = Inf
|
|
for s in et.enemies.values:
|
|
if not s.alive: continue
|
|
let d = hypot(s.x - x, s.y - y)
|
|
if d < bestDist:
|
|
bestDist = d
|
|
result = s
|
|
|
|
proc weakest*(et: EnemyTracker): EnemyState =
|
|
var bestEnergy = Inf
|
|
for s in et.enemies.values:
|
|
if not s.alive: continue
|
|
if s.energy < bestEnergy:
|
|
bestEnergy = s.energy
|
|
result = s
|