feat(PPO_Bot): network forward pass + action mapping (#14)
Two-hidden-layer MLP actor-critic (42→64→64→5/1) with stochastic actorForward, logStd floor at -3, and BotAction mapper wired into the run() loop. Assert-based test suite covers shapes, finiteness, logStd collapse, and all action range bounds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
## PPO_Bot — enemy tracker + state vector wired into the game loop.
|
||||
## Forward pass uses a random ActorCritic policy (weights not yet trained).
|
||||
|
||||
import std/os
|
||||
import arraymancer
|
||||
import tankroyale_botapi
|
||||
import network
|
||||
import actions
|
||||
import ./enemy_tracker
|
||||
import ./state_vector
|
||||
|
||||
const botJsonPath = currentSourcePath().parentDir / "PPO_Bot.json"
|
||||
|
||||
type PPOBot = ref object of Bot
|
||||
tracker: EnemyTracker
|
||||
|
||||
var ac = initActorCritic()
|
||||
|
||||
method onScannedBot*(bot: PPOBot, e: ScannedBotEvent) =
|
||||
bot.tracker.update(e.x, e.y, e.direction, e.speed, e.energy)
|
||||
|
||||
method onRoundStarted*(bot: PPOBot, e: RoundStartedEvent) =
|
||||
bot.tracker = initEnemyTracker()
|
||||
|
||||
method run(bot: PPOBot) =
|
||||
while isRunning():
|
||||
bot.tracker.deadReckon()
|
||||
|
||||
setRadarTurnRate(bot.tracker.getRadarTurnRate(
|
||||
getX(), getY(), getDirection(), getRadarDirection()))
|
||||
|
||||
let botData = BotStateData(
|
||||
x: getX(),
|
||||
y: getY(),
|
||||
direction: getDirection(),
|
||||
speed: getSpeed(),
|
||||
energy: getEnergy(),
|
||||
gunDirection: getGunDirection(),
|
||||
gunHeat: getGunHeat(),
|
||||
arenaWidth: float64(getArenaWidth()),
|
||||
arenaHeight: float64(getArenaHeight()),
|
||||
)
|
||||
|
||||
let state = buildStateVector(botData, bot.tracker)
|
||||
let (rawActs, _) = ac.actorForward(state)
|
||||
let acts = mapActions(rawActs, getSpeed().float32, getGunHeat().float32)
|
||||
|
||||
setTargetSpeed(acts.targetSpeed.float)
|
||||
setTurnRate(acts.turnRate.float)
|
||||
setGunTurnRate(acts.gunTurnRate.float)
|
||||
if acts.shouldFire:
|
||||
discard setFire(acts.firePower.float)
|
||||
go()
|
||||
|
||||
when isMainModule:
|
||||
var bot = PPOBot(tracker: initEnemyTracker())
|
||||
start(bot, botJsonPath)
|
||||
Reference in New Issue
Block a user