152fcba0cc
Added myEnergy, enemyEnergy, and canFire to ScanData. Energy fields quantize 0-150 → 8 bits each; gun ready is 1 bit (1 = can fire, 0 = can't). Updated total encoding from 100 to 117 bits. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
100 lines
2.9 KiB
Nim
100 lines
2.9 KiB
Nim
# BNNBot — binary encoding data collector.
|
|
# Radar lock on enemy, converts each scan to a 44-bit BinaryVector, prints it.
|
|
# No aiming, no firing — pure scan visualization for BNN research.
|
|
|
|
import std/[math, os, strutils]
|
|
import robocode_tankroyale_botapi
|
|
import radar_lock/radar_lock as radar_lock
|
|
import binary_encoding
|
|
|
|
const botJsonPath = currentSourcePath().parentDir / "BNNBot.json"
|
|
|
|
type
|
|
BNNBot = ref object of Bot
|
|
hasContact: bool
|
|
enemyBearing: float
|
|
lastEnemyX: float
|
|
lastEnemyY: float
|
|
hasLastPos: bool
|
|
velocity: float # signed velocity (from heading + speed)
|
|
heading: float # enemy heading (degrees)
|
|
distance: float
|
|
tick: int
|
|
prevVec: BinaryVector
|
|
hasPrev: bool
|
|
|
|
method onScannedBot*(bot: BNNBot, e: ScannedBotEvent) =
|
|
let bx = getX(); let by = getY()
|
|
bot.enemyBearing = directionTo(bx, by, e.x, e.y)
|
|
bot.distance = distanceTo(bx, by, e.x, e.y)
|
|
bot.heading = e.direction
|
|
bot.velocity = e.speed # signed: positive = forward, negative = reverse
|
|
if bot.hasLastPos:
|
|
discard # velocity from e.speed is more accurate; position delta kept for future use
|
|
bot.lastEnemyX = e.x
|
|
bot.lastEnemyY = e.y
|
|
bot.hasLastPos = true
|
|
bot.hasContact = true
|
|
|
|
let arenaW = getArenaWidth().float
|
|
let arenaH = getArenaHeight().float
|
|
let enemyX = e.x
|
|
let enemyY = e.y
|
|
let scan = ScanData(
|
|
bearing: bot.enemyBearing,
|
|
distance: bot.distance,
|
|
velocity: bot.velocity,
|
|
heading: bot.heading,
|
|
myWallN: arenaH - by,
|
|
myWallS: by,
|
|
myWallE: arenaW - bx,
|
|
myWallW: bx,
|
|
enemyWallN: arenaH - enemyY,
|
|
enemyWallS: enemyY,
|
|
enemyWallE: arenaW - enemyX,
|
|
enemyWallW: enemyX,
|
|
myEnergy: getEnergy(),
|
|
enemyEnergy: e.energy,
|
|
canFire: getGunHeat() <= 0.0,
|
|
)
|
|
let vec = encode(scan)
|
|
let hamming = if bot.hasPrev: hammingDistance(bot.prevVec, vec) else: 0
|
|
let similarity = if bot.hasPrev: TOTAL_BITS - hamming else: 0
|
|
let overlap = if bot.hasPrev: popcount(bitwiseAnd(bot.prevVec, vec)) else: 0
|
|
echo align($bot.tick, 4), " ", formatBinary(vec), " ", hamming, " ", similarity, " ", overlap
|
|
bot.prevVec = vec
|
|
bot.hasPrev = true
|
|
|
|
method onRoundStarted*(bot: BNNBot, e: RoundStartedEvent) =
|
|
setAdjustGunForBodyTurn(true)
|
|
setAdjustRadarForBodyTurn(true)
|
|
setAdjustRadarForGunTurn(true)
|
|
radar_lock.init()
|
|
bot.hasContact = false
|
|
bot.hasLastPos = false
|
|
bot.tick = 0
|
|
bot.hasPrev = false
|
|
setTargetSpeed(0.0)
|
|
setTurnRate(0.0)
|
|
|
|
method onGameStarted*(bot: BNNBot, e: GameStartedEventForBot) =
|
|
discard
|
|
|
|
method run*(bot: BNNBot) =
|
|
while isRunning():
|
|
inc bot.tick
|
|
setTargetSpeed(0.0)
|
|
setTurnRate(0.0)
|
|
|
|
if not bot.hasContact:
|
|
setRadarTurnRate(45.0)
|
|
go()
|
|
continue
|
|
|
|
setRadarTurnRate(radar_lock.doRadar(getRadarDirection(), bot.enemyBearing))
|
|
go()
|
|
|
|
when isMainModule:
|
|
var bot = BNNBot()
|
|
start(bot, botJsonPath)
|