Files
gplan-2/tools/clear_dominance_audit.py
T
DKChan d73508ffa9 feat(audit): 清图支配性对账重跑批——条款⑤现行值链重推(只读对账零数值改动;2026-09-19 用户指令经 plan 批准提前执行 06 待办对账义务;台账 86)——①重算器 tools/clear_dominance_audit.py(registry clause5_dominance 判式全参数 CLI 可配=难度曲线调参批常设重跑入口;E_dig 七型 67 权重池重推 (54+39u)÷67≈1.388〔u=1〕;V_mine 双口径:甲=注册公式 u×m_amb 连续对比 / 乙=极性矩阵负向字典加权 (42+50.4u)÷67≈1.379 主读数——注册公式成文于"所有雷→固定伏击"旧世界,矩阵批后踩雷惩罚按格型路由);②板形探针 smoke/board_stat_probe.gd(200 样本/行:实测幸存雷 10×10≈12.9 / 12×12≈22.4,远低于名义初布 23/34——"先布后删"落地值);③主结论(设计权威 design/research/audit-clear-dominance-2026-09-19.md):非完美态 18 语境全负、完美态唯一翻正面=L1 前段实测板形 +8.3——与 2026-09-14 重算批结构同向,裁决②"清图非严格支配=设计态"维持建议呈报(拍板归用户);保守地板缺口收窄 L1≈24/L2≈45 当量(u=1·对 C_min=8);护栏 B 防钓鱼上界被 C=13 常态越线(2026-09-17 压缩批未登记连带面)披露归调参批三选一;④analyze_playtest.py 增弃图刷新率/轮出口分布读数+--policy 过滤(刷新经济性监控条目分析侧缺口闭合,基线仍挂验收重测批)——双画像配对 1200 局实证:刷新流通关率全档位 ≥ 推到底流(L1 基线档 87% vs 73%)、实测盲挖踩雷 0.30–0.87/局 远低于判式保守计价 E[踩雷]≈12–21/板(均匀交错全池盲挖=构造性上界)、刷新策略 0.03–0.23 次/局几乎不发生——"清图被刷新淘汰"风险模拟面不成立;⑤登记面:registry clause5_dominance rerun_2026_09_19 回执+rerun_obligation 挂两工具入口+修订留痕块;难度曲线与Boss.md 正文对账句改写+P1 行回执指针;⑥验证:冒烟 317 项 0 失败(本批零游戏代码,冒烟作回归护栏)。边界:06 条目删除与 active.md 台账 86 两个共享状态文件留在主工作区随收口批收编(并行会话在飞 hunk 混载,不入本分支——registry 回执与本提交为分支侧登记事实源)
2026-09-19 15:40:09 +08:00

216 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""清图支配性对账重算工具(行动经济 条款⑤ · registry clause5_dominance)。
判式权威 = design/registry/entities.yaml clause5_dominance(挖穿残余池计价):
主判式 Δ_clear = [R_res + C_eff] − [X_res + Δr × s_ref] ≥ 0
保守地板 C_eff(min) ≥ X_res + Δr × s_ref
E[踩雷] = |M| × n_s ÷ (n_s + 1) (均匀交错模型)
n_s = (1 − ι) × |S| (域守卫 n_s < 1 ⇒ 不评估)
R_res = n_s × E_dig;X_res = E[踩雷] × V_mine;Δr = ⌈(n_s + E[踩雷]) ÷ AP_r⌉
s_ref = D_ref;停手侧 RAP 机会收益按零计价(显式假设)。
本工具 2026-09-19 随对账重跑批建立,是难度曲线调参批的常设重跑入口:
所有输入可经命令行覆盖(--d-ref --c-clear --ap-r --iota --m-amb --u ...),
重跑时按当期 .tres 行值更新默认值即可,公式本体不动。
单雷代价 / 单格收益的当量换算严格走 战斗结算「效果档位对照表」单一口径:
flat 类 E = 表值;percent 类 E = |层数×行值|÷100 × D_ref(每结算每层);
AC 轴换算 = AC 点数 × 5pp(d20 线性)× D_ref(假设登记,见审计报告)。
2026-09-19 起极性矩阵下踩雷惩罚按格型路由(不再固定伏击),故 V_mine 双口径:
甲 = 注册模型连续口径 V_mine = unit_count × m_amb(m_amb = 伏击行 magnitude);
乙 = 现行矩阵加权口径 V_mine = 负向字典按 67 权重池加权(主流读数)。
"""
import argparse
import math
# ============ 现行值链(2026-09-19 快照,出处见各注释;重跑批按当期 .tres 更新) ============
D_REF = 4 # settlement.tres equivalence_ref_damage(2026-09-17 压缩批 12→4)
P_PERFECT = 200 # settlement.tres(percent,÷100 = ×2 双份交付)
C_MIN, C_MAX = 8, 18 # reward.tres clear_blast power_min/max;期望口径 = 中点 13
AP_R = 6 # action_economy.tres ap_per_round(2026-09-16 压速批 8→6)
DIG_COST = 1 # action_economy.tres dig_ap_cost
IOTA = 0.88 # board_gen.tres inferability_target(判式 ι 代理)
# 效果行值(status_effects.tres,2026-09-19 快照)
ATTACK_UP_PCT = 50 # 增伤 +50%,duration 1,hero 侧
AC_UP_POINT = 1 # 护甲强化 +1 AC,duration 1
WEAKEN_PCT = 65 # 削弱 −65%(有效拍 1:duration 2 先兑付后衰减)
ENRAGE_PCT = 25 # 暴走 +25%,enemy 侧 side-wide
SAPPED_PCT = 25 # 乏力 −25%,hero 侧
AMBUSH_MAG = 1 # 伏击 +1 flat/层(2026-09-17 压缩批 3→1)
AMBUSH_STACKS = 2 # reward.tres ambush_double stacks(每雷伏击层数)
OFF_GUARD_AC = 2 # 失衡 AC −2(2026-09-18 换装)
# 直伤/群伤 flat 值(reward.tres,2026-09-17 ÷3 后)
SPARK_AOE = 1 # 爆裂粉尘(全体存活敌)
HEAL_MINOR = 1 # 急救敷料
HEAL_BACKLASH = 1 # 反噬震荡(主角直伤)
PIERCE_STRIKE = 2 # 穿刺弹(单目标克制直伤,必中全额)
MAGIC_BOLT = 2 # 魔法矢(同上)
PIERCE_SNARE = 2 # 穿刺陷阱(主角直伤)
MAGIC_RECOIL = 2 # 魔法反噬(主角直伤)
# 甲效矩阵(settlement.tres,加法核点数):基础值 + 点数,damage_floor=1
ARMOR_EFFECT = { # attack_type → {armor_type: 点数};切片 L1 全轻甲 / L2 除 Boss 全轻甲
"pierce": {"light": -1, "ward": 1, "heavy": 0},
"magic": {"light": 0, "ward": -1, "heavy": 1},
"normal": {"light": 0, "ward": 1, "heavy": -1},
}
# 格面资源池正向权重(reward.tres,2026-09-18 伤害道具批后,合计 67)
# 类型 → (权重);负向行 weight=0 不参与摇号,类型分布 = 正向权重
POOL_WEIGHTS = {"attack": 14, "defense": 11, "blast": 16, "heal": 2,
"weaken": 8, "pierce": 8, "magic": 8}
# 板形(|M| 幸存雷 / |S| 安全格)双口径
# 名义 = density×(W×H−9) 初布值(2026-09-14 重算批参考板形口径,连续性参照)
# 实测 = smoke/board_stat_probe.gd 200 样本/行均值("先布后删"落地值,主流读数)
BOARDS = {
"L1前段·名义(10x10)": {"M": 23, "S": 77},
"L1后段·名义(12x12)": {"M": 34, "S": 110},
"L2·名义(12x12)": {"M": 34, "S": 110},
"L1前段·实测(10x10)": {"M": 12.91, "S": 87.09},
"L1后段·实测(12x12)": {"M": 22.61, "S": 121.39},
"L2·实测(12x12)": {"M": 22.39, "S": 121.61},
}
def e_dig(u: float, d_ref: float, aoe_per_unit: bool = True) -> float:
"""单安全格期望收益(当量),格子池 67 权重加权。
u = 敌方单位数。hero 侧单目标效果不随 u 缩放(主角每轮出手一次);
enemy 侧 side-wide 效果(ac_up 承伤面 / spark_aoe 群伤 / weaken 全体减伤)随 u 缩放。
"""
w = POOL_WEIGHTS
total = sum(w.values())
attack = w["attack"] * ATTACK_UP_PCT / 100 * d_ref # 主角下一拍增伤
ac_up = w["defense"] * AC_UP_POINT * 0.05 * d_ref * u # 每个来敌拍 −5pp 命中
spark = w["blast"] * (SPARK_AOE * u if aoe_per_unit else SPARK_AOE) # 全体存活敌
heal = w["heal"] * HEAL_MINOR
weaken = w["weaken"] * WEAKEN_PCT / 100 * d_ref * u # 全体敌拍 ×0.35
pierce = w["pierce"] * max(1, PIERCE_STRIKE + ARMOR_EFFECT["pierce"]["light"]) # 轻甲口径
magic = w["magic"] * max(1, MAGIC_BOLT + ARMOR_EFFECT["magic"]["light"])
return (attack + ac_up + spark + heal + weaken + pierce + magic) / total
def v_mine_a(u: float, m_amb: float) -> float:
"""口径甲:注册模型连续口径 V_mine = unit_count × m_amb(registry 公式字面执行)。"""
return u * m_amb
def v_mine_b(u: float, d_ref: float) -> float:
"""口径乙:现行极性矩阵加权口径——踩雷兑付 = 该格类型负向行,按 67 权重池加权。
hero 侧固定(直伤三类 heal_backlash/snare/recoil + 乏力 sapped);
enemy 侧 side-wide(enrage 每敌拍 / off_guard 每敌拍命中上浮 / ambush_double 每敌拍 +2 flat)随 u 缩放。
"""
w = POOL_WEIGHTS
total = sum(w.values())
enrage = w["attack"] * ENRAGE_PCT / 100 * d_ref * u
off_guard = w["defense"] * OFF_GUARD_AC * 0.05 * d_ref * u # AC−2 → 每敌拍 +10pp 命中
backlash = w["heal"] * HEAL_BACKLASH
ambush = w["blast"] * AMBUSH_STACKS * AMBUSH_MAG * u
sapped = w["weaken"] * SAPPED_PCT / 100 * d_ref # 主角下一拍 −25%
snare = w["pierce"] * PIERCE_SNARE
recoil = w["magic"] * MAGIC_RECOIL
return (enrage + off_guard + backlash + ambush + sapped + snare + recoil) / total
def audit_shape(name: str, m: float, s: float, u: float, c_clear: float,
d_ref: float, ap_r: int, iota: float, v_mine: float,
e_dig: float, dig_cost: int) -> dict:
"""单板形单语境全量计算,返回判式各腿与判定。"""
n_s = (1 - iota) * s
if n_s < 1:
return {"name": name, "skip": True}
e_mine = m * n_s / (n_s + 1)
r_res = n_s * e_dig
x_res = e_mine * v_mine
dr = math.ceil((n_s + e_mine * dig_cost) / ap_r)
c_eff_normal = c_clear
c_eff_perfect = c_clear * P_PERFECT / 100
d_normal = (r_res + c_eff_normal) - (x_res + dr * d_ref)
d_perfect = (r_res + c_eff_perfect) - (x_res + dr * d_ref)
floor_req = x_res + dr * d_ref # 保守地板需求(对 C_eff)
return {
"name": name, "skip": False, "n_s": n_s, "e_mine": e_mine,
"r_res": r_res, "x_res": x_res, "dr": dr, "dr_cost": dr * d_ref,
"floor_req": floor_req, "gap_normal": floor_req - c_eff_normal,
"gap_perfect": floor_req - c_eff_perfect,
"d_normal": d_normal, "d_perfect": d_perfect,
}
def main() -> None:
ap = argparse.ArgumentParser(description="清图支配性(条款⑤)对账重算")
ap.add_argument("--d-ref", type=float, default=D_REF)
ap.add_argument("--c-clear", type=float, default=None,
help="清图奖励当量 C(默认 = (C_MIN+C_MAX)/2 = 13;传 8 得保守地板口径)")
ap.add_argument("--ap-r", type=int, default=AP_R)
ap.add_argument("--iota", type=float, default=IOTA)
ap.add_argument("--m-amb", type=float, default=float(AMBUSH_MAG),
help="口径甲的伏击行 magnitude(默认 1;传 2 = ambush_double 双层口径)")
ap.add_argument("--e-dig-discount", type=float, default=1.0,
help="E_dig 实现率折减(legacy 敏感性口径传 0.6)")
args = ap.parse_args()
c_clear = args.c_clear if args.c_clear is not None else (C_MIN + C_MAX) / 2
print(f"现行值链快照:D_ref={args.d_ref:g} C={c_clear:g}(min {C_MIN}/max {C_MAX}) "
f"AP_r={args.ap_r} ι={args.iota} p_perfect={P_PERFECT} RAP零价假设照旧")
print(f"E_dig(67权重池加权当量): u=1 {e_dig(1, args.d_ref):.3f} · u=2 {e_dig(2, args.d_ref):.3f} · "
f"u=3 {e_dig(3, args.d_ref):.3f}(折减 ×{args.e_dig_discount:g} 后同乘)")
print(f"V_mine 口径甲(u×m_amb, m_amb={args.m_amb:g}): u=1 {v_mine_a(1, args.m_amb):.3f} · "
f"u=2 {v_mine_a(2, args.m_amb):.3f} · u=3 {v_mine_a(3, args.m_amb):.3f}")
print(f"V_mine 口径乙(极性矩阵加权): u=1 {v_mine_b(1, args.d_ref):.3f} · "
f"u=2 {v_mine_b(2, args.d_ref):.3f} · u=3 {v_mine_b(3, args.d_ref):.3f}")
print()
for vm_label, vm_fn in [("口径甲(注册模型 V_mine=u×m_amb)", lambda u: v_mine_a(u, args.m_amb)),
("口径乙(现行矩阵加权 V_mine)", lambda u: v_mine_b(u, args.d_ref))]:
print(f"### 主判式 · {vm_label} · C={c_clear:g}")
print("| 板形 | u | n_s | E[踩雷] | R_res | X_res | Δr(代价) | Δ_clear 非完美 | Δ_clear 完美 | 判定 |")
print("|---|---|---|---|---|---|---|---|---|---|")
for bname, b in BOARDS.items():
for u in (1, 2, 3):
ed = e_dig(u, args.d_ref) * args.e_dig_discount
r = audit_shape(bname, b["M"], b["S"], u, c_clear, args.d_ref,
args.ap_r, args.iota, vm_fn(u), ed, DIG_COST)
if r["skip"]:
continue
verdict = "✓" if r["d_perfect"] >= 0 and r["d_normal"] >= 0 else (
"完美✓" if r["d_perfect"] >= 0 else "✗")
print(f"| {bname} | {u} | {r['n_s']:.2f} | {r['e_mine']:.2f} | {r['r_res']:.1f} | "
f"{r['x_res']:.1f} | {r['dr']}({r['dr_cost']:.0f}) | {r['d_normal']:+.1f} | "
f"{r['d_perfect']:+.1f} | {verdict} |")
print()
print("### 保守地板(C_eff(min)=C_MIN)需求与缺口 · 口径乙")
print("| 板形 | u | 地板需求 X_res+Δr×s_ref | 缺口(对 min) | 缺口(对完美 ×2) |")
print("|---|---|---|---|---|")
for bname, b in BOARDS.items():
for u in (1, 3):
ed = e_dig(u, args.d_ref) * args.e_dig_discount
r = audit_shape(bname, b["M"], b["S"], u, float(C_MIN), args.d_ref,
args.ap_r, args.iota, v_mine_b(u, args.d_ref), ed, DIG_COST)
if r["skip"]:
continue
print(f"| {bname} | {u} | {r['floor_req']:.1f} | +{r['gap_normal']:.1f} | +{r['gap_perfect']:.1f} |")
print()
# 护栏 B(防钓鱼——退化板刷清图奖励上界):⌈(|S|min − |R0|max) ÷ AP_r⌉ × s_ref ÷ 2
# |S|min = min_safe_count 当期行集(50/60);|R0|max = 20 经验值(无登记供给方)
print("### 护栏 B 复核(防钓鱼上界,D_ref 口径)")
for s_min in (50, 60):
ub = math.ceil((s_min - 20) / args.ap_r) * args.d_ref / 2
print(f"|S|min={s_min}: 上界 = ⌈({s_min}−20)/{args.ap_r}⌉×{args.d_ref:g}÷2 = {ub:g}"
f" → C={c_clear:g} {'✓' if c_clear <= ub else '越 %.1f×' % (c_clear / ub)}"
f" / 完美 C_eff={c_clear * P_PERFECT / 100:g} "
f"{'✓' if c_clear * P_PERFECT / 100 <= ub else '越 %.1f×' % (c_clear * P_PERFECT / 100 / ub)}")
if __name__ == "__main__":
main()