254c7dc997
- Gun harness: virtual bullet tracker, rolling fitness, auto-selector - Guns: head-on, linear (extrapolation), circular (integrated formula), tsetlin machine (learning) - Movement: phantom meteor gravity engine (danger histograms, phantom bullets, fire detection) - Radar: harness + radar_lock adapter - Color-coded modules: turret/bullet color per gun, body per movement, scan per radar - Beats Target, SpinBot, Crazy, TrackFire in 10-round battles
27 lines
1.1 KiB
Nim
27 lines
1.1 KiB
Nim
## Gun selector — picks best gun×power, computes aim angle, gates firing.
|
||
## Fires highest power with acceptable hit rate when gun is aimed within
|
||
## threshold and gunHeat == 0.
|
||
|
||
import std/math
|
||
import gun_interface
|
||
import virtual_bullets
|
||
|
||
const AimThresholdDeg* = 2.0 ## max angle error to fire; ponytail: tune per bot
|
||
|
||
proc aimAngle*(selfX, selfY, targetX, targetY: float): float =
|
||
## Absolute bearing in degrees (0=East, CCW+) toward (targetX, targetY).
|
||
result = radToDeg(arctan2(targetY - selfY, targetX - selfX))
|
||
|
||
proc shouldFire*(currentGunDir, targetAngle, gunHeat: float): bool =
|
||
## Returns true when gun is close enough and cool enough to fire.
|
||
var delta = (targetAngle - currentGunDir) mod 360.0
|
||
if delta > 180.0: delta -= 360.0
|
||
elif delta < -180.0: delta += 360.0
|
||
abs(delta) <= AimThresholdDeg and gunHeat <= 0.0
|
||
|
||
proc selectShot*(t: VirtualTracker): (GunId, int, float) =
|
||
## Returns (gunId, powerBinIdx, power) — the shot to take this tick.
|
||
let gunId = t.bestGun()
|
||
let (binIdx, power) = t.bestPower(gunId)
|
||
result = (gunId, binIdx, power)
|