0384e2ba6a
Changes: - Fixed fire power at 3.0 (removes hitRateEMA power ladder noise that cleared exemplars mid-battle and corrupted learning) - Relative velocity encoding: input uses (velDir - bearing) instead of absolute velDir, so exemplars generalize across Walls' starting walls - Fix test winner detection to use per-round score delta instead of rank field (rank in round_ended is cumulative battle rank, not round winner) - Keep exemplars across power changes (no longer relevant with fixed power) - Store lastBulletSpeed at fire time for accurate EVALUATE lead prediction Result: 2/10 rounds won vs Walls (Nim); first-round win now possible from round 1 when aimer generalizes from relative velocity patterns. Bottleneck: sparse exemplars in early rounds; energy bleeds at P3 cold-start. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
2.7 KiB
Nim
65 lines
2.7 KiB
Nim
## Bullet economy test: SNNBot vs WallsBot.
|
|
## Prints per-round and summary stats for tuning. No hard pass/fail.
|
|
## Requires TR server JARs (set TR_SERVER_JAR / TR_BATTLE_RUNNER env vars).
|
|
## Set TR_SAMPLE_BOTS to point to sample-bots directory (e.g. sample-bots-nim-linux-1.0.7).
|
|
|
|
import std/[os, strformat]
|
|
import test_framework/battle_result
|
|
|
|
const
|
|
DefaultServerJar = "/home/davide/Projects/tank-royale/server/build/libs/robocode-tankroyale-server-0.35.5-all.jar"
|
|
DefaultRunnerJar = "/home/davide/Projects/tank-royale/runner/examples/lib/robocode-tankroyale-runner.jar"
|
|
DefaultSampleBots = "/home/davide/Downloads/robocode-tankroyale/sample-bots-nim-linux-1.0.7"
|
|
|
|
let serverJar = getEnv("TR_SERVER_JAR", DefaultServerJar)
|
|
let runnerJar = getEnv("TR_BATTLE_RUNNER", DefaultRunnerJar)
|
|
let sampleBotsDir = getEnv("TR_SAMPLE_BOTS", DefaultSampleBots)
|
|
|
|
if not fileExists(serverJar) or not fileExists(runnerJar):
|
|
echo "Skipping: JAR files not found (set TR_SERVER_JAR / TR_BATTLE_RUNNER to override)"
|
|
quit(0)
|
|
|
|
if not dirExists(sampleBotsDir):
|
|
echo "Skipping: sample bots directory not found at ", sampleBotsDir
|
|
echo "Set TR_SAMPLE_BOTS to override"
|
|
quit(0)
|
|
|
|
import test_framework/test_framework
|
|
|
|
const
|
|
snnbotDir = currentSourcePath().parentDir.parentDir
|
|
|
|
let wallsbotDir = sampleBotsDir / "Walls"
|
|
|
|
let r = runBattle(@[snnbotDir, wallsbotDir], rounds = 10)
|
|
|
|
# Per-round stats
|
|
echo "=== Per-round results ==="
|
|
var snnWins, wallsWins: int
|
|
var prevSnn, prevWalls: int
|
|
for rnd in r.rounds:
|
|
var snn, walls: BotRoundResult
|
|
for br in rnd.results:
|
|
if br.name == "SNNBot": snn = br
|
|
if br.name == "Walls (Nim)": walls = br
|
|
let snnDelta = snn.score - prevSnn
|
|
let wallsDelta = walls.score - prevWalls
|
|
prevSnn = snn.score
|
|
prevWalls = walls.score
|
|
# Use per-round score delta to determine round winner (rank field is cumulative battle rank)
|
|
let winner = if snnDelta > wallsDelta: "SNNBot" else: "Walls"
|
|
if winner == "SNNBot": inc snnWins else: inc wallsWins
|
|
echo fmt"Round {rnd.round:2}: {winner} wins | SNNBot +{snnDelta}(={snn.score}) rank={snn.rank} survived={snn.survived} | Walls +{wallsDelta}(={walls.score}) rank={walls.rank} survived={walls.survived}"
|
|
|
|
# Summary
|
|
echo ""
|
|
echo "=== Summary (10 rounds) ==="
|
|
var snnFinal, wallsFinal: BotResult
|
|
for b in r.results:
|
|
if b.name == "SNNBot": snnFinal = b
|
|
if b.name == "Walls (Nim)": wallsFinal = b
|
|
|
|
echo fmt"SNNBot : wins={snnWins}/10 totalScore={snnFinal.totalScore} survivalRounds={snnFinal.survivalCount} firstPlaces={snnFinal.firstPlaces}"
|
|
echo fmt"Walls : wins={wallsWins}/10 totalScore={wallsFinal.totalScore} survivalRounds={wallsFinal.survivalCount} firstPlaces={wallsFinal.firstPlaces}"
|
|
echo fmt"Win rate : {snnWins * 100 div 10}%"
|