0cc682152db71de061dbca535dfb14435f367112
Wave queues (guess_factor, decay_gf, knn_gun): predict() stored ONE wave per tick while onResult() popped one per resolved bullet (~4/tick), so the queue drained to empty within a few dozen ticks, ~3 of every 4 resolutions returned without learning, and the survivor paired with a same-tick wave (bearingDelta ~= 0) pinning the histogram at centre. PROOF: GF.vHits == HeadOn.vHits and DecayGF.vHits == HeadOn.vHits byte-for-byte in every one of 50 rounds — the guns had degenerated to HeadOn. Now each gun keeps a per-bin FIFO with an O(1) head cursor. At most one push per (tick, bin) so the fire site's 5th predict() call is a no-op, and onResult pops the oldest wave of its OWN bin via e.bulletPower. Aiming math untouched (it was already correct: 0 deg = East, CCW+). maxBullets 2048 -> 8192: the rack spawns 52 bullets/tick so the ring wrapped every ~39 ticks while a long power-3 shot needs ~90, silently discarding unresolved bullets and biasing every measured hit rate by range. Added a droppedBullets counter so a future overflow is measurable, and wavePushes/ waveStarved counters on the three guns. After the fix: vDropped = 0 and vStarved = 0 across all 48 recorded rounds. fitnessFor is now exported, deterministic (enemies iterated in ascending id order) and shared by the selector and the stats dump, replacing a hand-rolled merge in ModularBot that never advanced its window head. Round lines gain additive keys: vDropped, vStarved.
Description
No description provided
Languages
Nim
73.7%
Python
18%
Shell
3.7%
Java
3.5%
HTML
1%
Other
0.1%