fix(BNNBot): correct sin/cos for bullet position, gentler 1-bit exploration

- Swap sin/cos in virtual bullet position calc to match Tank Royale convention
- Change exploration from flipping each bit with 50% chance to flipping exactly 1 random bit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 23:51:22 +02:00
parent 22aefbddb6
commit 481f284e1a
2 changed files with 4 additions and 5 deletions
Binary file not shown.
+4 -5
View File
@@ -94,8 +94,8 @@ method onScannedBot*(bot: BNNBot, e: ScannedBotEvent) =
let bulletDist = b.bulletSpeed * float(b.trace.age)
if bulletDist >= b.fireDist or b.trace.age >= TRACE_MAX_AGE:
let bulletX = b.fireX + sin(degToRad(b.aimAngleDeg)) * bulletDist
let bulletY = b.fireY + cos(degToRad(b.aimAngleDeg)) * bulletDist
let bulletX = b.fireX + cos(degToRad(b.aimAngleDeg)) * bulletDist
let bulletY = b.fireY + sin(degToRad(b.aimAngleDeg)) * bulletDist
let enemyDist = hypot(bulletX - bot.lastEnemyX, bulletY - bot.lastEnemyY)
if enemyDist < 36.0:
bot.net.learn(b.trace, HIT_REWARD)
@@ -110,9 +110,8 @@ method onScannedBot*(bot: BNNBot, e: ScannedBotEvent) =
# epsilon-greedy exploration
if rand(1.0) < bot.epsilon:
for j in 0..<OUTPUT_BITS:
if rand(1.0) < 0.5:
outVec[j] = 1'u8 - outVec[j] # flip bit
let flipIdx = rand(OUTPUT_BITS - 1)
outVec[flipIdx] = 1'u8 - outVec[flipIdx]
bot.epsilon = max(EPSILON_MIN, bot.epsilon * EPSILON_DECAY)
let aimOffset = decodeOutput(outVec)