feat(SNNBot): add bullet economy test against WallsBot
Add --max-speed flag to TestBattleRunner (sets defaultTurnsPerSecond=-1 for unlimited TPS). Add SNNBot_garage/tests/test_bullet_economy.nim: 10-round vs WallsBot, prints per-round and summary stats for tuning. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
## 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).
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
let serverJar = getEnv("TR_SERVER_JAR", DefaultServerJar)
|
||||||
|
let runnerJar = getEnv("TR_BATTLE_RUNNER", DefaultRunnerJar)
|
||||||
|
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)
|
||||||
|
|
||||||
|
import test_framework/test_framework
|
||||||
|
|
||||||
|
const
|
||||||
|
snnbotDir = currentSourcePath().parentDir.parentDir
|
||||||
|
wallsbotDir = currentSourcePath().parentDir.parentDir.parentDir /
|
||||||
|
"common_libs" / "test_framework" / "adversaries" / "WallsBot"
|
||||||
|
|
||||||
|
let r = runBattle(@[snnbotDir, wallsbotDir], rounds = 10)
|
||||||
|
|
||||||
|
# Per-round stats
|
||||||
|
echo "=== Per-round results ==="
|
||||||
|
var snnWins, wallsWins: int
|
||||||
|
for rnd in r.rounds:
|
||||||
|
var snn, walls: BotRoundResult
|
||||||
|
for br in rnd.results:
|
||||||
|
if br.name == "SNNBot": snn = br
|
||||||
|
if br.name == "WallsBot": walls = br
|
||||||
|
let winner = if snn.rank < walls.rank: "SNNBot" else: "WallsBot"
|
||||||
|
if winner == "SNNBot": inc snnWins else: inc wallsWins
|
||||||
|
echo fmt"Round {rnd.round:2}: {winner} wins | SNNBot score={snn.score} survived={snn.survived} | WallsBot score={walls.score} 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 == "WallsBot": wallsFinal = b
|
||||||
|
|
||||||
|
echo fmt"SNNBot : wins={snnWins}/10 totalScore={snnFinal.totalScore} survivalRounds={snnFinal.survivalCount} firstPlaces={snnFinal.firstPlaces}"
|
||||||
|
echo fmt"WallsBot : wins={wallsWins}/10 totalScore={wallsFinal.totalScore} survivalRounds={wallsFinal.survivalCount} firstPlaces={wallsFinal.firstPlaces}"
|
||||||
|
echo fmt"Win rate : {snnWins * 100 div 10}%"
|
||||||
@@ -19,6 +19,7 @@ public class TestBattleRunner {
|
|||||||
|
|
||||||
String serverUrl = null;
|
String serverUrl = null;
|
||||||
int rounds = 1;
|
int rounds = 1;
|
||||||
|
boolean maxSpeed = false;
|
||||||
List<String> botDirs = List.of();
|
List<String> botDirs = List.of();
|
||||||
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
@@ -26,6 +27,7 @@ public class TestBattleRunner {
|
|||||||
case "--server-url" -> serverUrl = args[++i];
|
case "--server-url" -> serverUrl = args[++i];
|
||||||
case "--rounds" -> rounds = Integer.parseInt(args[++i]);
|
case "--rounds" -> rounds = Integer.parseInt(args[++i]);
|
||||||
case "--bot-dirs" -> botDirs = Arrays.asList(args[++i].split(","));
|
case "--bot-dirs" -> botDirs = Arrays.asList(args[++i].split(","));
|
||||||
|
case "--max-speed" -> maxSpeed = true;
|
||||||
default -> { System.err.println("Unknown arg: " + args[i]); System.exit(1); }
|
default -> { System.err.println("Unknown arg: " + args[i]); System.exit(1); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +38,12 @@ public class TestBattleRunner {
|
|||||||
final String url = serverUrl;
|
final String url = serverUrl;
|
||||||
final List<BotEntry> bots = botDirs.stream().map(BotEntry::of).collect(Collectors.toList());
|
final List<BotEntry> bots = botDirs.stream().map(BotEntry::of).collect(Collectors.toList());
|
||||||
final int numRounds = rounds;
|
final int numRounds = rounds;
|
||||||
final var setup = BattleSetup.classic(s -> s.setNumberOfRounds(numRounds));
|
final boolean runMaxSpeed = maxSpeed;
|
||||||
|
// -1 = max TPS (no speed limit); see ServerCli.kt: "where -1 means maximum TPS"
|
||||||
|
final var setup = BattleSetup.classic(s -> {
|
||||||
|
s.setNumberOfRounds(numRounds);
|
||||||
|
if (runMaxSpeed) s.setDefaultTurnsPerSecond(-1);
|
||||||
|
});
|
||||||
|
|
||||||
// Debug: check what JSON files the runner will find for each bot dir
|
// Debug: check what JSON files the runner will find for each bot dir
|
||||||
for (String dir : botDirs) {
|
for (String dir : botDirs) {
|
||||||
|
|||||||
Reference in New Issue
Block a user