j146 ledger: the field shape restores a real safe set offline (filter broken 63.5%->30.4%) and is a live null on damage/run and round wins; 375 battles, 5 arms
This commit is contained in:
@@ -258,6 +258,7 @@ type TurnStats = object
|
||||
broken: int
|
||||
ownHeatSum: float
|
||||
ownHot: int
|
||||
safeSum: int ## j146: sum of the SAFE candidate-set size per pick
|
||||
turnRateSum: float
|
||||
hardTurn: int
|
||||
holdSum: int
|
||||
@@ -288,6 +289,7 @@ proc replayTurn(arm, envspec: string): TurnStats =
|
||||
putEnv("TR_TFIL_COMMIT_LOG", "")
|
||||
loadTfilCommitEnv()
|
||||
loadTfilHeatEnv()
|
||||
loadTfilHeatShapeEnv() # j146: the heat SHAPE knobs (corridor/wall/bullet)
|
||||
randomize(Seed)
|
||||
var m = initTFIL()
|
||||
let states = loadStates()
|
||||
@@ -328,6 +330,7 @@ proc replayTurn(arm, envspec: string): TurnStats =
|
||||
result.pathHeatSum += ph
|
||||
if ph > 10.0: inc result.hot
|
||||
if m.lastPickPromoted: inc result.broken
|
||||
result.safeSum += m.lastPickSafe
|
||||
if hadPicks and
|
||||
sqrt((ws.selfX-prev.x)^2 + (ws.selfY-prev.y)^2) < ArriveR2: inc result.reached
|
||||
result.distSum += sqrt((m.commitTarget.x - ws.selfX)^2 +
|
||||
@@ -387,3 +390,50 @@ for s in trows:
|
||||
echo &"| {s.arm} | {mean(s.turnRateSum, s.ticks).formatFloat(ffDecimal,2)} | {pct(s.hardTurn, s.ticks)} | " &
|
||||
&"{mean(s.holdSum.float, s.picks).formatFloat(ffDecimal,1)} | {pct(s.reached, s.picks)} | " &
|
||||
&"{mean(s.distSum, s.picks).formatFloat(ffDecimal,0)} px |"
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# j146 — THE FIELD SHAPE, the mechanism ruler. The upstream cause j145 surfaced:
|
||||
# 59% of picks break the hard filter, because corridor 20 is TWICE
|
||||
# PathDangerThreshold 10 and tfil's own bullet heat (core 10) is exactly the
|
||||
# threshold, so a bullet is never dangerous by itself.
|
||||
#
|
||||
# Arms are the FIVE shapes pre-registered in docs/movement_campaign.md
|
||||
# (Batch 7), all on the j144 base so the shape is isolated on the current best
|
||||
# tfil. The metrics: `filter broken` (the share of picks that had to promote a
|
||||
# hot tile because FEWER THAN TWO tiles were safe) and `mean safe candidates`
|
||||
# (the size of the set the picker drew from) are the MECHANISM; mean |turn| and
|
||||
# mean path heat are the cost.
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
const ShapeBase = "TR_MOVEMENT=tfil TR_TFIL_COMMIT_ARRIVAL=1 TR_TFIL_NOREV_SPEED=4"
|
||||
let shapeArms = [
|
||||
("shipped 20/30/10/10/5", ShapeBase &
|
||||
" TR_TFIL_CORRIDOR_HEAT=20 TR_TFIL_WALL_HOTNESS=30 TR_TFIL_WALL_RADIANCE=10" &
|
||||
" TR_TFIL_BULLET_CORE=10 TR_TFIL_BULLET_AURA=5"),
|
||||
("middle 10/15/5/20/10", ShapeBase &
|
||||
" TR_TFIL_CORRIDOR_HEAT=10 TR_TFIL_WALL_HOTNESS=15 TR_TFIL_WALL_RADIANCE=5" &
|
||||
" TR_TFIL_BULLET_CORE=20 TR_TFIL_BULLET_AURA=10"),
|
||||
("corr10 10/30/10/10/5", ShapeBase &
|
||||
" TR_TFIL_CORRIDOR_HEAT=10 TR_TFIL_WALL_HOTNESS=30 TR_TFIL_WALL_RADIANCE=10" &
|
||||
" TR_TFIL_BULLET_CORE=10 TR_TFIL_BULLET_AURA=5"),
|
||||
("bullets 20/30/10/20/10", ShapeBase &
|
||||
" TR_TFIL_CORRIDOR_HEAT=20 TR_TFIL_WALL_HOTNESS=30 TR_TFIL_WALL_RADIANCE=10" &
|
||||
" TR_TFIL_BULLET_CORE=20 TR_TFIL_BULLET_AURA=10"),
|
||||
("nofield 0/0/0/20/10", ShapeBase &
|
||||
" TR_TFIL_CORRIDOR_HEAT=0 TR_TFIL_WALL_HOTNESS=0 TR_TFIL_WALL_RADIANCE=0" &
|
||||
" TR_TFIL_BULLET_CORE=20 TR_TFIL_BULLET_AURA=10"),
|
||||
]
|
||||
|
||||
echo "\n\n══ j146 FIELD SHAPE — mechanism ruler ══\n"
|
||||
echo "columns: CORRIDOR / WALL_HOTNESS / WALL_RADIANCE / BULLET_CORE / BULLET_AURA\n"
|
||||
var srows: seq[TurnStats]
|
||||
for (name, envspec) in shapeArms:
|
||||
srows.add replayTurn(name, envspec)
|
||||
|
||||
echo &"| arm | picks | filter broken | mean safe candidates | mean path heat | path heat >10 | mean \\|turn\\| | >90 deg |"
|
||||
echo "|---|---:|---:|---:|---:|---:|---:|---:|"
|
||||
for s in srows:
|
||||
echo &"| {s.arm} | {s.picks} | {pct(s.broken, s.picks)} | " &
|
||||
&"{mean(s.safeSum.float, s.picks).formatFloat(ffDecimal,2)} | " &
|
||||
&"{mean(s.pathHeatSum, s.picks).formatFloat(ffDecimal,2)} | {pct(s.hot, s.picks)} | " &
|
||||
&"{mean(s.turnSum, s.picks).formatFloat(ffDecimal,1)} | {pct(s.bigTurn, s.picks)} |"
|
||||
|
||||
Reference in New Issue
Block a user