diff --git a/ModularBot_garage/src/ModularBot.nim b/ModularBot_garage/src/ModularBot.nim index a8ba324..8c61453 100644 --- a/ModularBot_garage/src/ModularBot.nim +++ b/ModularBot_garage/src/ModularBot.nim @@ -137,6 +137,7 @@ type prevGun: int prevRadar: int prevTarget: int + cfgDirty: bool ## gun/target/radar changed this tick; emit one config line at tick end roundNumber: int realShotsFired: int realHits: int @@ -205,19 +206,25 @@ proc resolveOwnBullet(bot: ModularBot, bulletId: int): int = if result >= 0: bot.bulletGun.del(bulletId) -proc printConfig(bot: ModularBot, changed: string = "") = - let gunName = GunNames[bot.currentGun] +proc printConfig(bot: ModularBot, forceAll: bool = false) = + ## One line describing the config in use for the tick being reported. Only the + ## fields that changed since the previous line are highlighted green. The gun + ## field is omitted until a gun has actually been selected this round, so a + ## round-start line never claims a gun that was not chosen. + let rst = CLR_RST + let gc = if bot.currentGun != bot.prevGun or forceAll: CLR_CHANGE else: "" + let rc = if bot.radarMode != bot.prevRadar or forceAll: CLR_CHANGE else: "" + let tc = if bot.currentTargetId != bot.prevTarget or forceAll: CLR_CHANGE else: "" let radarName = if bot.radarMode == 0: "radar_lock" else: "melee_scan" let moveName = if bot.isRamming: "rammer" else: "tfil" - let gc = if bot.currentGun != bot.prevGun or changed == "all": CLR_CHANGE else: "" - let rc = if bot.radarMode != bot.prevRadar or changed == "all": CLR_CHANGE else: "" - let tc = if bot.currentTargetId != bot.prevTarget or changed == "all": CLR_CHANGE else: "" - let rst = CLR_RST - echo "[config] " & gc & "gun=" & gunName & (if gc != "": rst else: "") & - " | move=" & moveName & - " | " & rc & "radar=" & radarName & (if rc != "": rst else: "") & - " | enemies=" & $bot.enemyTracker.allAlive().len & - " target=" & tc & "#" & $bot.currentTargetId & (if tc != "": rst else: "") + var line = "[config] " + if bot.currentGun >= 0 and bot.currentGun < GunNames.len: + line &= gc & "gun=" & GunNames[bot.currentGun] & (if gc != "": rst else: "") & " | " + line &= "move=" & moveName & + " | " & rc & "radar=" & radarName & (if rc != "": rst else: "") & + " | enemies=" & $bot.enemyTracker.allAlive().len & + " target=" & tc & "#" & $bot.currentTargetId & (if tc != "": rst else: "") + echo line bot.prevGun = bot.currentGun bot.prevRadar = bot.radarMode bot.prevTarget = bot.currentTargetId @@ -448,7 +455,8 @@ method onRoundStarted*(bot: ModularBot, e: RoundStartedEvent) = # ponytail: default to melee until confirmed 1v1 via scans, avoids stale enemyCount issue bot.radarMode = 1 # Start in melee_scan; will switch to radar_lock (0) if tracker confirms 1v1 bot.moveTracker.resetRound(getX(), getY(), getDirection(), getSpeed()) - bot.currentGun = 0 + # currentGun stays -1 ("no gun chosen yet") until run() picks one; printConfig + # omits the gun field while it is negative. # Apply radar colors for initial mode if bot.radarMode == 0: setRadarColor("#004444") @@ -456,7 +464,8 @@ method onRoundStarted*(bot: ModularBot, e: RoundStartedEvent) = else: setRadarColor("#443300") setScanColor("#4D3D0D") - bot.printConfig("all") + bot.cfgDirty = false + bot.printConfig(forceAll = true) # tracker fitness persists across rounds (rolling window carries over) method onBotDeath*(bot: ModularBot, e: BotDeathEvent) = @@ -520,7 +529,7 @@ method run*(bot: ModularBot) = if candidateId != bot.currentTargetId: bot.currentTargetId = candidateId bot.targetSwitchTick = bot.tick - bot.printConfig("target") + bot.cfgDirty = true # emit at tick end, after gun selection if bot.currentTargetId >= 0: bot.lastKnownTargetId = bot.currentTargetId @@ -593,7 +602,7 @@ method run*(bot: ModularBot) = else: setRadarColor("#443300") setScanColor("#4D3D0D") - bot.printConfig("radar") + bot.cfgDirty = true # emit at tick end, after gun selection let radarRate = if bot.radarMode == 0: bot.radar.computeScan(bot.lastState) @@ -694,6 +703,7 @@ method run*(bot: ModularBot) = bot.gunSelectionCount[selectedGun] += 1 if selectedGun != bot.currentGun: bot.currentGun = selectedGun + bot.cfgDirty = true # gun switch: emit the config line at tick end case selectedGun of 0: setTurretColor("#FF3333"); setBulletColor("#FF6666") of 1: setTurretColor("#3366FF"); setBulletColor("#6699FF") @@ -754,6 +764,12 @@ method run*(bot: ModularBot) = setGunTurnRate(normDelta) + # Emit exactly one config line per tick, at the END of the tick, so the gun + # field reflects the selection made above rather than the previous tick's. + if bot.cfgDirty: + bot.printConfig() + bot.cfgDirty = false + proc seedSelectorRng() = ## Seed the process-global RNG exactly once at bot startup so the gun ## selector's "random" tie-break (`chooseFromFit` -> rand) actually varies