cdde60d79f
- Add gotoTick/aimToTick controller functions (#25) - Update network dims: actor 5→6, state 42→44 (#26) - Rewrite mapActions for 6-dim command space (#27) - Delete stale weight files (shape mismatch) - Fix existing tests for new signatures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
46 lines
1.5 KiB
Nim
46 lines
1.5 KiB
Nim
## actions.nim — map raw network output to Tank Royale bot commands.
|
||
|
||
import arraymancer
|
||
import std/math
|
||
import ./controllers
|
||
|
||
func sigmoid(x: float): float = 1.0 / (1.0 + exp(-x))
|
||
|
||
type
|
||
BotActions* = object
|
||
targetSpeed*: float
|
||
turnRate*: float
|
||
gunTurnRate*: float
|
||
shouldFire*: bool
|
||
firePower*: float
|
||
gotoX*: float
|
||
gotoY*: float
|
||
aimToX*: float
|
||
aimToY*: float
|
||
|
||
proc mapActions*(rawActions: Tensor[float32],
|
||
gunHeat: float,
|
||
arenaWidth, arenaHeight: float,
|
||
botX, botY, direction, speed, gunDirection: float): BotActions =
|
||
## rawActions: [6] tensor from actorForward.
|
||
## Dims 0–1: goto x/y, 2–3: aimTo x/y, 4: fire decision, 5: fire power.
|
||
let gotoX = sigmoid(rawActions[0].float) * arenaWidth
|
||
let gotoY = sigmoid(rawActions[1].float) * arenaHeight
|
||
let aimToX = sigmoid(rawActions[2].float) * arenaWidth
|
||
let aimToY = sigmoid(rawActions[3].float) * arenaHeight
|
||
let fireDec = tanh(rawActions[4].float)
|
||
let fp = sigmoid(rawActions[5].float) * 2.9 + 0.1
|
||
|
||
let (ts, tr) = gotoTick(gotoX, gotoY, botX, botY, direction, speed)
|
||
let gtr = aimToTick(aimToX, aimToY, botX, botY, gunDirection)
|
||
|
||
result.gotoX = gotoX
|
||
result.gotoY = gotoY
|
||
result.aimToX = aimToX
|
||
result.aimToY = aimToY
|
||
result.targetSpeed = ts
|
||
result.turnRate = tr
|
||
result.gunTurnRate = gtr
|
||
result.shouldFire = fireDec >= 0.0 and gunHeat <= 0.0
|
||
result.firePower = fp
|