Files
gplan-2/tools/clear_dominance_audit.py
T
DKChan bbd49abfb0 docs(术语): 设计文档术语刷新批全量入库——2026-10-18 用户裁定(金币/插旗/旗/雷格/惩罚格 五词)design/+tools/ 域落文
- 术语表 v1.13:GP 唯一正式命名(删「局内金币」别名)+旗/控制词条更名封印/控制+封印定性由「插旗的对外表达」更正为正式动作名(全库统一、非比喻)+禁用字面从对外命名扩为全库+删「机制文档内部用语不受限」条款+退役词对照表补三行(金币→GP/插旗→封印/旗→封印印记)+危险格词条「被旗控制」→「被封印控制」+B3 豁免例举去旗
- 机检扩容 tools/doc_term_audit.py:RETIRED_TERMS 新增 金币→GP、插旗|标旗→封印 两行(DEFAULT_DIRS 不变,game/ 扫描归代码批);拔旗|撤旗行继任措辞随批换代(插旗不可逆→封印不可逆)
- GDD 全域正文换代约 200 行/31 文件:金币→GP(金币袋→GP 袋)、插旗/标旗→封印、雷格/惩罚格→危险格(2026-10-11 退役批存量补扫)、旗概念→封印印记(旗判定→封印判定/标中旗→封印标中/标错旗→标错封印/旗格→封印格/旗位→封印位等复合词系);00-游戏概念「封印降级为类型风味词」定性翻转;修订记录/版本历史/禁令引举/更名记载等留档行零动
- registry/entities.yaml(信标网络可达性/事件序/回执驱动三处)+art 五件(art-bible 封印印记六处/comfyui 背旗→背负封印印记/两清单)+dev 七件(architecture 旗集→封印集/code-conventions-cases/test-conventions/架构图 html json 四件)随批换代
- tools 四脚本注释与图内标注换代(clear_dominance_audit/render_sample_sheet×2/analyze_playtest;代码标识符零动归代码批)
- design/qa/代码术语审计报告-2026-10-18.md 随批入库(本批参考素材,06:578 引用闭合 doc_link 死链)
- 06-待办清单/术语表两在途脏件(代码术语批 06 登记+A 表头「不用→禁用」)随批一并入库

自检:doc_term_audit --strict 零疑似现行(45 文件 434 命中全留档类);文档域六闸验收通过无新增红(gdd_lint R3 对 00 正文修订注记一次打回已去注记化改写;doc_link 死链经报告入库闭合);正文残留仅 06:73「拔旗」一处(件派生动词白名单豁免语境、机检同款豁免,设计意图记录不动)
2026-10-18 06:15:38 +08:00

306 lines
18 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 ...),
重跑时按当期 .tres 行值更新默认值即可,公式本体不动。
单雷代价 / 单格收益的当量换算严格走 战斗结算「效果档位对照表」单一口径:
flat 类 E = 表值;percent 类 E = |层数×行值|÷100 × D_ref(每结算每层);
AC 轴换算 = AC 点数 × 5pp(d20 线性)× D_ref(假设登记,见审计报告)。
【2026-10-05 判式换代批口径(迭代14②号卡 T0)】
- 池 67→77(补 action 6 / gp 2;clear_blast 系清图槽对象不入格池)。
- 直伤雷负向三行 6/8/8(backlash/snare/recoil,2026-10-01 数值修复+10-03 转正);
正向 pierce_strike/magic_bolt 维持 flat 2;heal_minor 2(Package B 第 2 轮)。
- 清图槽 C_MIN/MAX 8/18→24/40(中点 32);AP_r 6→8(2026-09-16 压速批 8→6 后回摆)。
- off_guard 换 ac 轴 −1(0.2u 模型:点数×5pp×D_ref=0.2 当量/每敌拍)。
- 伏击历史口径(口径甲 u×m_amb / AMBUSH_MAG/STACKS)退役删除——伏击机制已退役,
V_mine 只保留现行矩阵加权口径(原口径乙升为主口径)。
- V_mine 换现行九型负向字典(enrage/off_guard/警觉/backlash/sapped/snare/recoil/
ap_drain/gp_lose——ap_drain 按 A6 flat 1、gp_lose 按 A5 代理 2 计)。
- 新增 β 比值带判读与逐型净期望输出(原方案报告 §四/§九,已退役 git 1da9a41):
β(u)=V_mine/E_dig ∈ [1.2, 2.5];条件一 (1−ρ̂)E_dig−ρ̂V_mine ≥ 0(下限 0,上限归 β_hi);
条件二 E[标中兑付] ≥ (1+δ)·E_dig(δ=1.25 provisional,兑付溢价形态 a)。
"""
import argparse
import math
# ============ 现行值链(2026-10-05 判式换代批快照,出处见各注释;重跑批按当期 .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 = 24, 40 # reward.tres clear_blast power_min/max(2026-10-01 数值修复批 8/18→24/40);期望口径 = 中点 32
AP_R = 8 # action_economy.tres ap_per_round(2026-09-16 压速批 8→6 后回摆 8)
DIG_COST = 1 # action_economy.tres dig_ap_cost
IOTA = 0.88 # board_gen.tres inferability_target(判式 ι 代理)
# 效果行值(status_effects.tres,2026-10-05 快照)
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 侧
OFF_GUARD_AC = 1 # 失衡 AC −1(0.2u 模型:1 点 × 5pp × D_ref = 0.2 当量/每敌拍)
ALERT_EQUIV = 0.2 # 警觉(敌 AC+1×1拍):主角每拍恰 1 攻 × 1 拍寿命 ⇒ 0.2 当量,u 无关(假设 A4)
# 直伤/群伤 flat 值(reward.tres,2026-10-05 快照)
SPARK_AOE = 1 # 爆裂粉尘(全体存活敌)
HEAL_MINOR = 2 # 急救敷料(Package B 第 2 轮 1→2)
HEAL_BACKLASH = 6 # 反噬震荡(主角直伤,2026-10-01 4→6 / 10-03 转正)
PIERCE_STRIKE = 2 # 穿刺弹(单目标克制直伤,必中全额)
MAGIC_BOLT = 2 # 魔法矢(同上)
PIERCE_SNARE = 8 # 穿刺陷阱(主角直伤,2026-10-01 5→8 / 10-03 转正)
MAGIC_RECOIL = 8 # 魔法反噬(主角直伤,2026-10-01 5→8 / 10-03 转正)
AP_UP = 1 # 行动点 +1(当量 = flat 表值 1,机会成本口径更高仅登记——假设 A6)
GP_COIN = 3 # GP 袋 +3 GP(gp 当量 = flat power 代理——假设 A5,口径空白登记)
GP_LOSE = 2 # 破财 −2GP(同上代理)
# 甲效矩阵(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-10-05 快照,合计 77)
# 类型 → (权重);负向行 weight=0 不参与摇号,类型分布 = 正向权重
# clear_blast pool_tag=clear_default 系清图槽对象,不入格池(地图战斗资源.md §清图槽)。
POOL_WEIGHTS = {"attack": 14, "defense": 11, "blast": 16, "heal": 4,
"weaken": 8, "pierce": 8, "magic": 8, "action": 6, "gp": 2}
# β 比值带(2026-10-04 用户裁 P4:[1.2, 2.5];u=3 登记态 1.17 微破下限=点名不强制回滚)
BETA_LO, BETA_HI = 1.2, 2.5
# δ 旗溢价(2026-10-04 用户裁 P3:形态 a 兑付溢价,δ=1.25 provisional ⇒ 兑付按同型正向 ×(1+δ))
DELTA = 0.25
# 板形(|M| 幸存雷 / |S| 安全格)双口径
# 名义 = density×(W×H−9) 初布值(2026-09-14 重算批参考板形口径,连续性参照)
# 实测 = smoke/board_stat_probe.gd 200 样本/行均值("先布后删"落地值,主流读数)
# (实测值沿用 2026-09-19 board_stat_probe 读数;板形行值此后未变,不强制复跑)
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:
"""单安全格期望收益(当量),格子池 77 权重加权。
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"])
action = w["action"] * AP_UP
gp = w["gp"] * GP_COIN
return (attack + ac_up + spark + heal + weaken + pierce + magic + action + gp) / total
def v_mine(u: float, d_ref: float) -> float:
"""现行极性矩阵加权口径(九型负向字典)——踩雷兑付 = 该格类型负向行,按 77 权重池加权。
hero 侧固定(直伤三类 heal_backlash/snare/recoil + 乏力 sapped + ap_drain + gp_lose);
enemy 侧 side-wide(enrage 每敌拍 / off_guard 每敌拍命中上浮)随 u 缩放;
警觉按 0.2 当量固定(假设 A4)。
"""
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−1 → 每敌拍 +5pp 命中
alert = w["blast"] * ALERT_EQUIV
backlash = w["heal"] * HEAL_BACKLASH
sapped = w["weaken"] * SAPPED_PCT / 100 * d_ref # 主角下一拍 −25%
snare = w["pierce"] * PIERCE_SNARE
recoil = w["magic"] * MAGIC_RECOIL
ap_drain = w["action"] * AP_UP
gp_lose = w["gp"] * GP_LOSE
return (enrage + off_guard + alert + backlash + sapped + snare + recoil
+ ap_drain + gp_lose) / total
def w_flag_hit(u: float, d_ref: float, prem_pct: int = 125) -> float:
"""标中旗兑付聚合当量 W(u)——整数量级实现口径(与机制同式:各型四舍五入取整后折算)。
迭代14② T4 起为条件二常设判读式:条件二 = W(u) ≥ (1+δ)·E_dig(u)。
取整跟随机制(GDScript round=半分远离零),非 Python banker's rounding。
1 点量纲行(ac_up/action/spark)取整地板=×1.0——u=3 聚合微欠的成因(登记面)。
"""
w = POOL_WEIGHTS
total = sum(w.values())
def sc(x: float) -> int:
return int(math.floor(x * prem_pct / 100.0 + 0.5))
attack = w["attack"] * sc(ATTACK_UP_PCT) / 100 * d_ref
ac_up = w["defense"] * sc(AC_UP_POINT) * 0.05 * d_ref * u
spark = w["blast"] * (sc(SPARK_AOE) * u)
heal = w["heal"] * sc(HEAL_MINOR)
weaken = w["weaken"] * sc(WEAKEN_PCT) / 100 * d_ref * u
pierce = w["pierce"] * max(1, sc(PIERCE_STRIKE) + ARMOR_EFFECT["pierce"]["light"])
magic = w["magic"] * max(1, sc(MAGIC_BOLT) + ARMOR_EFFECT["magic"]["light"])
action = w["action"] * sc(AP_UP)
gp = w["gp"] * sc(GP_COIN)
return (attack + ac_up + spark + heal + weaken + pierce + magic + action + gp) / total
def per_type_table(u: float, d_ref: float) -> list:
"""逐型 P_t/N_t 明细(当量),供条件净期望计算。返回 [(型, P_t, N_t)]。"""
return [
("attack", ATTACK_UP_PCT / 100 * d_ref, ENRAGE_PCT / 100 * d_ref * u),
("defense", AC_UP_POINT * 0.05 * d_ref * u, OFF_GUARD_AC * 0.05 * d_ref * u),
("blast", float(SPARK_AOE * u), ALERT_EQUIV),
("heal", float(HEAL_MINOR), float(HEAL_BACKLASH)),
("weaken", WEAKEN_PCT / 100 * d_ref * u, SAPPED_PCT / 100 * d_ref),
("pierce", float(max(1, PIERCE_STRIKE + ARMOR_EFFECT["pierce"]["light"])), float(PIERCE_SNARE)),
("magic", float(max(1, MAGIC_BOLT + ARMOR_EFFECT["magic"]["light"])), float(MAGIC_RECOIL)),
("action", float(AP_UP), float(AP_UP)),
("gp", float(GP_COIN), float(GP_LOSE)),
]
def audit_shape(name: str, m: float, s: float, u: float, c_clear: float,
d_ref: float, ap_r: int, iota: float, v_mine_v: float,
e_dig_v: 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_v
x_res = e_mine * v_mine_v
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="清图支配性(条款⑤)对账重算 + 判式换代面板(条款3)")
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 = 32;传 24 得保守地板口径)")
ap.add_argument("--ap-r", type=int, default=AP_R)
ap.add_argument("--iota", type=float, default=IOTA)
ap.add_argument("--rho-nominal", type=float, default=0.25, help="名义雷率(判式主口径)")
ap.add_argument("--rho-measured", type=float, default=0.129, help="实测幸存雷率(10×10 包络口径)")
ap.add_argument("--delta", type=float, default=DELTA, help="旗溢价系数 δ(兑付溢价形态 a)")
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(77权重池加权当量): 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=1 {v_mine(1, args.d_ref):.3f} · "
f"u=2 {v_mine(2, args.d_ref):.3f} · u=3 {v_mine(3, args.d_ref):.3f}")
print()
print("### 条款3 判式换代面板(β 比值带 + 条件一聚合健康式 + 条件二旗溢价)")
print(f"β 带 = [{BETA_LO:g}, {BETA_HI:g}](2026-10-04 用户裁 P4) 兑付溢价 ×(1+δ) = ×{1 + args.delta:g}(形态 a)")
print("| u | E_dig | V_mine | β=V/E | 带判定 | 条件一 盲挖净期望(名义ρ) | 条件一 盲挖净期望(实测ρ̂) | 条件二 W(u) | 条件二 阈值(1+δ)E_dig | 条件二判定 |")
print("|---|---|---|---|---|---|---|---|---|---|")
for u in (1, 2, 3):
ed = e_dig(u, args.d_ref)
vm = v_mine(u, args.d_ref)
beta = vm / ed
verdict = "✓带内" if BETA_LO <= beta <= BETA_HI else (
"✗破下限(登记态)" if beta < BETA_LO else "✗破上限")
blind_nom = (1 - args.rho_nominal) * ed - args.rho_nominal * vm
blind_meas = (1 - args.rho_measured) * ed - args.rho_measured * vm
# 条件二(T4 起机制在位):W=整数量级标中兑付聚合(取整跟随机制),阈值 =(1+δ)·E_dig
wfh = w_flag_hit(u, args.d_ref, int(round((1 + args.delta) * 100)))
thresh = (1 + args.delta) * ed
cond2 = "✓转绿" if wfh >= thresh else "✗微欠(整数量级取整地板,登记面)"
print(f"| {u} | {ed:.3f} | {vm:.3f} | {beta:.2f} | {verdict} | "
f"{blind_nom:+.2f} | {blind_meas:+.2f} | {wfh:.3f} | {thresh:.3f} | {cond2} |")
print()
print("### 逐型条件净期望 (1−ρ)P_t − ρN_t(当量/格,u=1,名义 ρ 与实测 ρ̂ 双列)")
print("| 型 | P_t | N_t | 净期望(名义ρ) | 净期望(实测ρ̂) | 判(名义) |")
print("|---|---|---|---|---|---|")
for t, p, n in per_type_table(1, args.d_ref):
net = (1 - args.rho_nominal) * p - args.rho_nominal * n
net_m = (1 - args.rho_measured) * p - args.rho_measured * n
verdict = "✓" if net > 1e-9 else ("踩线" if abs(net) <= 1e-9 else "✗破线")
print(f"| {t} | {p:g} | {n:g} | {net:+.2f} | {net_m:+.2f} | {verdict} |")
for u in (2, 3):
cells = " · ".join(f"{t}({(1 - args.rho_nominal) * p - args.rho_nominal * n:+.2f})"
for t, p, n in per_type_table(u, args.d_ref))
print(f"u={u} 净期望: {cells}")
print()
print(f"### 主判式(条款⑤)· 九型矩阵加权 V_mine · 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, v_mine(u, args.d_ref), 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(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()