## Anti-surfer gun: inverse of GF histogram — aim at the VALLEY bin. ## Wave surfers dodge to where they predict bullets won't be (the GF peak). ## They congregate at the valley → aim there to punish their dodge. ## Bins: 31, same as GFGun. Learns from virtual bullet outcomes. import std/[math, strformat] import gun_harness/gun_interface const ASBins = 31 ASPrior = 0.1 DebugAS* = false type ASWave = object fireX, fireY: float fireBearing: float AntiSurferGun* = object bins: array[ASBins, float] waves: seq[ASWave] cachedTick: int cachedWaveStored: bool proc initAntiSurferGun*(): AntiSurferGun = result.cachedTick = -1 # Same triangular head-on prior as GFGun — cold-start aims head-on. let center = (ASBins - 1) div 2 # = 15 for i in 0.. PI: bearingDelta -= 2.0*PI while bearingDelta < -PI: bearingDelta += 2.0*PI let gf = if mea > 1e-10: clamp(bearingDelta / mea, -1.0, 1.0) else: 0.0 let centerIdx = asToIndex(gf) when DebugAS: echo fmt"[as-dbg] onResult: delta={radToDeg(bearingDelta):.1f}° MEA={radToDeg(mea):.1f}° GF={gf:.2f} bin={centerIdx}" for i in 0..