## Averaged-lead gun: mean prediction from linear, circular, and wall-bounce guns. ## Smooths noise when enemy movement is between analytical models. import gun_harness/gun_interface import guns/linear import guns/circular import guns/wall_bounce type AveragedLeadGun* = object linear: LinearGun circular: CircularGun wallBounce: WallBounceGun debugGraphics*: bool proc initAveragedLeadGun*(): AveragedLeadGun = AveragedLeadGun(wallBounce: initWallBounceGun(), debugGraphics: false) proc predict*(g: var AveragedLeadGun, state: WorldState, bulletSpeed: float): GunPrediction = # No tick cache: every sub-gun's lead depends on bulletSpeed (dist/bulletSpeed), # so caching one result per tick and reusing it for all four power bins would # silently collapse every bin onto the first. linear/wallBounce are stateless # and cheap; circular only caches its speed-independent omega internally. let lp = g.linear.predict(state, bulletSpeed) let cp = g.circular.predict(state, bulletSpeed) let wp = g.wallBounce.predict(state, bulletSpeed) var px = (lp.x + cp.x + wp.x) / 3.0 var py = (lp.y + cp.y + wp.y) / 3.0 px = clamp(px, BotRadius, state.arenaWidth - BotRadius) py = clamp(py, BotRadius, state.arenaHeight - BotRadius) GunPrediction(x: px, y: py) proc onResult*(g: var AveragedLeadGun, e: FeedbackEvent) = discard # analytical average — no learning