From b7b10af8119ad29b9a92d9fa091da090d60c7db6 Mon Sep 17 00:00:00 2001 From: Davide Cappellini Date: Mon, 24 Aug 2026 00:01:38 +0200 Subject: [PATCH] feat: OscillatorBot sparring partner for GA gun testing (#64) Co-Authored-By: Claude Opus 4.6 --- OscillatorBot/OscillatorBot.json | 11 ++++++++ OscillatorBot/OscillatorBot.nim | 48 ++++++++++++++++++++++++++++++++ OscillatorBot/OscillatorBot.sh | 3 ++ OscillatorBot/config.nims | 1 + 4 files changed, 63 insertions(+) create mode 100644 OscillatorBot/OscillatorBot.json create mode 100644 OscillatorBot/OscillatorBot.nim create mode 100755 OscillatorBot/OscillatorBot.sh create mode 100644 OscillatorBot/config.nims diff --git a/OscillatorBot/OscillatorBot.json b/OscillatorBot/OscillatorBot.json new file mode 100644 index 0000000..4d64a9f --- /dev/null +++ b/OscillatorBot/OscillatorBot.json @@ -0,0 +1,11 @@ +{ + "name": "OscillatorBot", + "version": "0.1.0", + "authors": ["Davide Cappellini"], + "description": "Predictable zigzag sparring partner for gun testing", + "homepage": "", + "countryCodes": ["IT"], + "gameTypes": ["classic", "1v1"], + "platform": "Nim", + "programmingLang": "Nim" +} diff --git a/OscillatorBot/OscillatorBot.nim b/OscillatorBot/OscillatorBot.nim new file mode 100644 index 0000000..f071468 --- /dev/null +++ b/OscillatorBot/OscillatorBot.nim @@ -0,0 +1,48 @@ +# OscillatorBot — predictable zigzag sparring partner for GA gun testing. +# Reverses direction + turn every PERIOD ticks. Head-on targeting only. + +import std/[math, os] +import tankroyale_botapi + +const botJsonPath = currentSourcePath().parentDir / "OscillatorBot.json" + +const + SPEED = 7.0 # forward/backward speed + PERIOD = 25 # ticks between direction reversals + +type OscillatorBot = ref object of Bot + tickCount: int + moveSign: float # +1 forward, -1 backward + turnSign: float # +1 right, -1 left + +method onRoundStarted*(bot: OscillatorBot, e: RoundStartedEvent) = + setAdjustGunForBodyTurn(true) + setAdjustRadarForBodyTurn(true) + setAdjustRadarForGunTurn(true) + bot.tickCount = 0 + bot.moveSign = 1.0 + bot.turnSign = 1.0 + +method onScannedBot*(bot: OscillatorBot, e: ScannedBotEvent) = + # Head-on targeting: aim gun directly at enemy, fire medium power + let bearing = directionTo(getX(), getY(), e.x, e.y) + let gunDelta = normalizeRelativeAngle(bearing - getGunDirection()) + setGunTurnRate(gunDelta.clamp(-MAX_GUN_TURN_RATE, MAX_GUN_TURN_RATE)) + if abs(gunDelta) < 10.0 and getGunHeat() <= 0.0: + discard setFire(2.0) + +method run*(bot: OscillatorBot) = + while isRunning(): + inc bot.tickCount + if bot.tickCount mod PERIOD == 0: + bot.moveSign *= -1.0 + bot.turnSign *= -1.0 + + setTargetSpeed(bot.moveSign * SPEED) + setTurnRate(bot.turnSign * 4.0) + setRadarTurnRate(45.0) # spin radar to keep scanning + go() + +when isMainModule: + var bot = OscillatorBot(moveSign: 1.0, turnSign: 1.0) + start(bot, botJsonPath) diff --git a/OscillatorBot/OscillatorBot.sh b/OscillatorBot/OscillatorBot.sh new file mode 100755 index 0000000..e8cd5f7 --- /dev/null +++ b/OscillatorBot/OscillatorBot.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd "$(dirname "$0")" +exec ./OscillatorBot 2>> /tmp/oscillatorbot_stderr.log diff --git a/OscillatorBot/config.nims b/OscillatorBot/config.nims new file mode 100644 index 0000000..5457dba --- /dev/null +++ b/OscillatorBot/config.nims @@ -0,0 +1 @@ +--path:"../libs"