1e8f0d342a
P0. Three of the five launchers ran ./<Bot> (a tracked binary at the bot root) while config.nims sets outdir=out and both the test framework's compileBots and a manual 'nim c src/<Bot>.nim' write to out/. SittingDuck and OscillatorBot correctly ran ./out/<Bot>; RandomMover, PatternMover and WaveSurfer did not. cmp confirms the root and out binaries differed for all three. Consequence: the previous session's adversary fixes were compiled into out/ and never executed. Every gauntlet and every capture ran the OLD code. This is almost certainly why the user's instinct that these bots were still bugged was correct while the code claimed otherwise. Fixed by pointing all five launchers at ./out/<Bot>, and by deleting the three stale root binaries so the trap cannot recur. Verified end to end through the booter: WaveSurfer went from standing still 96.2% of ticks with a 1398-tick longest standstill, to rest 12.3% / mean speed 6.69 / longest zero run 18 / perpendicular 0.845. Also honours GUN_STATS_PATH in test_gauntlet_5bots.nim (same knob ModularBot reads) so pooled gauntlet runs append to one file instead of clobbering the default. NOTE for a follow-up: the out/ binaries are still TRACKED build artifacts, which is the same class of hazard that caused this. Untracking them (as was done for ModularBot_garage/ModularBot) would remove the failure mode entirely.
70 lines
3.1 KiB
Nim
70 lines
3.1 KiB
Nim
## Gun gauntlet: ModularBot vs all 5 adversaries, 10 rounds each.
|
|
## Dumps per-gun stats via ModularBot's onRoundEnded to /tmp/gun_stats.jsonl.
|
|
## nim c -r --path:../../common_libs tests/test_gauntlet_5bots.nim
|
|
|
|
import std/[os, strutils, strformat, tables]
|
|
import test_framework/server_manager
|
|
import test_framework/bot_compiler
|
|
import test_framework/runner_process
|
|
import test_framework/battle_result
|
|
|
|
const
|
|
modularBotDir = currentSourcePath().parentDir.parentDir
|
|
adversariesDir = "/home/davide/Projects/SirRoboGarage/common_libs/test_framework/adversaries"
|
|
serverJar = "/home/davide/Projects/tank-royale/server/build/libs/robocode-tankroyale-server-0.35.5-all.jar"
|
|
runnerJar = "/home/davide/Projects/tank-royale/runner/examples/lib/robocode-tankroyale-runner.jar"
|
|
|
|
if not fileExists(serverJar):
|
|
echo "SKIP: server JAR not found at " & serverJar
|
|
quit(0)
|
|
if not fileExists(runnerJar):
|
|
echo "SKIP: runner JAR not found at " & runnerJar
|
|
quit(0)
|
|
|
|
putEnv("TR_SERVER_JAR", serverJar)
|
|
putEnv("TR_BATTLE_RUNNER", runnerJar)
|
|
putEnv("TR_BATTLE_RUNNER_DIR", "/home/davide/Projects/SirRoboGarage/tools/battle_runner")
|
|
|
|
# Pre-compile ModularBot once
|
|
discard compileBots(@[modularBotDir])
|
|
echo "[gauntlet] ModularBot compiled OK"
|
|
|
|
proc runBattle(label, enemyName, enemyDir: string) =
|
|
let sep = "=".repeat(60)
|
|
echo "\n" & sep
|
|
echo " " & label
|
|
echo sep
|
|
let bots = @[modularBotDir, enemyDir]
|
|
discard compileBots(@[enemyDir]) # ensure adversary is compiled
|
|
# Write session marker so analysis can map rounds to enemy name.
|
|
# Honor GUN_STATS_PATH (same knob ModularBot reads) so repeated pooled runs
|
|
# can append to one dedicated file instead of clobbering the default.
|
|
let statsPath = getEnv("GUN_STATS_PATH", "/tmp/gun_stats.jsonl")
|
|
block:
|
|
let lf = open(statsPath, fmAppend)
|
|
lf.writeLine("{\"session_start\":\"" & enemyName & "\"}")
|
|
lf.close()
|
|
let raw = runBattleRunner(getServerUrl(), bots, 10, 300_000, true)
|
|
let r = parseServerOutput(raw)
|
|
var mbScore = 0; var enScore = 0
|
|
for b in r.results:
|
|
if b.name == "ModularBot": mbScore = b.totalScore
|
|
elif b.name == enemyName: enScore = b.totalScore
|
|
let winner = if mbScore >= enScore: "ModularBot" else: enemyName
|
|
echo fmt" ModularBot: {mbScore} {enemyName}: {enScore} -> {winner} wins"
|
|
echo fmt" Rounds played: {r.rounds.len}"
|
|
|
|
# Write summary line to gauntlet log
|
|
let logLine = fmt"[{label}] ModularBot={mbScore} {enemyName}={enScore} winner={winner} rounds={r.rounds.len}"
|
|
let lf = open("/tmp/gun_gauntlet_results.log", fmAppend)
|
|
lf.writeLine(logLine)
|
|
lf.close()
|
|
|
|
ensureServer()
|
|
runBattle("Battle 1/5: vs SittingDuck", "SittingDuck", adversariesDir / "SittingDuck")
|
|
runBattle("Battle 2/5: vs OscillatorBot","OscillatorBot", adversariesDir / "OscillatorBot")
|
|
runBattle("Battle 3/5: vs RandomMover", "RandomMover", adversariesDir / "RandomMover")
|
|
runBattle("Battle 4/5: vs PatternMover", "PatternMover", adversariesDir / "PatternMover")
|
|
runBattle("Battle 5/5: vs WaveSurfer", "WaveSurfer", adversariesDir / "WaveSurfer")
|
|
echo "\nGauntlet complete. Stats in " & getEnv("GUN_STATS_PATH", "/tmp/gun_stats.jsonl") & " and /tmp/gun_gauntlet_results.log"
|