diff --git a/ModularBot_garage/src/ModularBot.nim b/ModularBot_garage/src/ModularBot.nim index 458b9c7..c633fc0 100644 --- a/ModularBot_garage/src/ModularBot.nim +++ b/ModularBot_garage/src/ModularBot.nim @@ -1,5 +1,5 @@ ## ModularBot — plugin gun architecture tracer bullet. -## Guns: HeadOnGun (0), LinearGun (1), TsetlinGun (2), CircularGun (3), GFGun (4), PatternMatcherGun (5), AntiSurferGun (6), WallBounceGun (7), AccelGun (8), StopShotGun (9), DisplacementGun (10), AveragedLeadGun (11), DecayGFGun (12) via GunHarness. +## Guns: HeadOnGun (0), LinearGun (1), TsetlinGun (2), CircularGun (3), GFGun (4), PatternMatcherGun (5), WallBounceGun (6), AccelGun (7), StopShotGun (8), DisplacementGun (9), AveragedLeadGun (10), DecayGFGun (11), KNNGun (12) via GunHarness. ## Radar: RadarLockModule (1v1) / MeleeScanModule (2+ enemies), auto-switched per tick. ## Movement: OscillatorModule (perpendicular strafing). @@ -17,7 +17,6 @@ import guns/circular import guns/tsetlin import guns/guess_factor import guns/pattern_matcher -import guns/anti_surfer import guns/wall_bounce import guns/accel_predictor import guns/stop_shot @@ -36,7 +35,7 @@ import targeting/target_selector const botJsonPath = currentSourcePath().parentDir / "ModularBot.json" const DebugVBullets = false const DebugCircular = false -const GunNames = ["HeadOn", "Linear", "Tsetlin", "Circular", "GuessFactor", "Pattern", "AntiSurf", "WallBounce", "Accel", "StopShot", "Displace", "AvgLead", "DecayGF", "KNN"] +const GunNames = ["HeadOn", "Linear", "Tsetlin", "Circular", "GuessFactor", "Pattern", "WallBounce", "Accel", "StopShot", "Displace", "AvgLead", "DecayGF", "KNN"] const CLR_GUN = "\e[33m" # yellow @@ -64,7 +63,6 @@ type tsetlin: TsetlinGun guessFactor: GFGun patternMatcher: PatternMatcherGun - antiSurfer: AntiSurferGun wallBounce: WallBounceGun accelGun: AccelGun stopShot: StopShotGun @@ -92,7 +90,7 @@ type roundNumber: int realShotsFired: int realHits: int - gunSelectionCount: array[14, int] + gunSelectionCount: array[13, int] lastKnownTargetId: int ## persists through death, used for round-end stats proc printConfig(bot: ModularBot, changed: string = "") = @@ -184,7 +182,7 @@ method onRoundEnded*(bot: ModularBot, e: RoundEndedEventForBot) = f var gunsArr = newJArray() - for gid in 0..<14: + for gid in 0..<13: var totalShots = 0 var totalHits = 0 for binIdx in 0..= 0 and data exists; else aggregate. + ## Ties (within TieMargin) are broken randomly to avoid index-0 bias. ## ponytail: O(n*bins), fine for small gun counts let fit = t.fitnessFor(targetId) proc bestAmong(fit: seq[GunFitness], requireMin: bool): GunId = var bestRate = -1.0 - result = 0 for gunId in 0.. bestRate: - bestRate = r - result = gunId + if r > bestRate: bestRate = r + # Floor check: if nothing hits well enough, HeadOn is the safe default + if bestRate < MinHitRateFloor: return 0 + var tied: seq[GunId] + for gunId in 0..= bestRate - TieMargin: + tied.add(gunId) + break + if tied.len == 0: return 0 + return tied[rand(tied.len - 1)] var anyQualifies = false for gunId in 0..