import dev.robocode.tankroyale.runner.*; import dev.robocode.tankroyale.client.model.*; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * BNNBot validation battle: BNNBot vs Target (1 round, embedded server). * * Env vars: * BNN_BOT_DIR — path to BNNBot directory (must contain BNNBot.json + BNNBot.sh) * SAMPLE_BOTS_DIR — path to sample bots archive * BNNBOT_CSV — forwarded to bot process: "1" enables CSV output * ENEMY_BOT — name of enemy bot subfolder under SAMPLE_BOTS_DIR (default: Target) * NUM_ROUNDS — number of rounds to run (default: 5) * * Usage: java -cp ".:$JAR" RunBNNBattle */ public class RunBNNBattle { static final Map idToName = new ConcurrentHashMap<>(); public static void main(String[] args) { Logger.getLogger("dev.robocode.tankroyale").setLevel(Level.WARNING); String bnnBotDir = requireEnv("BNN_BOT_DIR"); String sampleBots = requireEnv("SAMPLE_BOTS_DIR"); String enemyBot = System.getenv().getOrDefault("ENEMY_BOT", "Target"); int numRounds = Integer.parseInt(System.getenv().getOrDefault("NUM_ROUNDS", "5")); System.out.println("Enemy: " + enemyBot + " Rounds: " + numRounds); try (var runner = BattleRunner.create(b -> b.embeddedServer().suppressServerOutput())) { var setup = BattleSetup.classic(s -> s.setNumberOfRounds(numRounds)); var bots = List.of( BotEntry.of(bnnBotDir), BotEntry.of(sampleBots + "/" + enemyBot) ); var owner = new Object(); try (var handle = runner.startBattleAsync(setup, bots)) { handle.getOnGameStarted().on(owner, event -> { System.out.println("=== GAME STARTED ==="); for (var p : event.getParticipants()) { idToName.put(p.getId(), p.getName()); System.out.printf(" #%d %s%n", p.getId(), p.getName()); } System.out.printf("%-6s %-12s %-10s%n", "Turn", "Name", "RadarDir"); System.out.println("-".repeat(40)); }); handle.getOnTickEvent().on(owner, event -> { int turn = event.getTurnNumber(); for (var state : event.getBotStates()) if (state.getName() != null) idToName.putIfAbsent(state.getId(), state.getName()); }); handle.getOnRoundEnded().on(owner, event -> System.out.printf("%n=== ROUND %d ENDED (turn %d) ===%n", event.getRoundNumber(), event.getTurnNumber())); var results = handle.awaitResults(); System.out.printf("%n=== RESULTS (%d rounds) ===%n", results.getNumberOfRounds()); for (var r : results.getResults()) System.out.printf(" #%d %-25s %d pts%n", r.getRank(), r.getName(), r.getTotalScore()); } } } static String requireEnv(String name) { var v = System.getenv(name); if (v == null || v.isBlank()) { System.err.println("Error: " + name + " env var not set"); System.exit(1); } return v; } }