#!/usr/bin/env python3 # -*- coding: utf-8 -*- """清图支配性对账重算工具(行动经济 条款⑤ · 挖穿残余池计价)。 判式权威 = design/gdd/systems/排雷循环/行动经济.md 条款⑤(公式本体同时内联于本 docstring): 主判式 Δ_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 机会收益按零计价(显式假设)。 本工具是难度曲线调参的常设重跑入口: 所有输入可经命令行覆盖(--d-ref --c-clear --ap-r --iota ...), 重跑时按当期 .tres 行值更新默认值即可,公式本体不动。 单雷代价 / 单格收益的当量换算严格走 战斗结算「效果档位对照表」单一口径: flat 类 E = 表值;percent 类 E = |层数×行值|÷100 × D_ref(每结算每层); AC 轴换算 = AC 点数 × 5pp(d20 线性)× D_ref(假设登记,见审计报告)。 【现行判式口径】 - 池权重合计 77(含 action 6 / gp 2;clear_blast 系清图槽对象不入格池)。 - 直伤雷负向三行 6/8/8(backlash/snare/recoil); 正向 pierce_strike/magic_bolt 维持 flat 2;heal_minor 2(Package B 第 2 轮)。 - 清图槽 C_MIN/C_MAX = 24/40(中点 32);AP_r = 8。 - off_guard 走 ac 轴 −1(0.2u 模型:点数×5pp×D_ref=0.2 当量/每敌拍)。 - V_mine 为九型负向字典口径(enrage/off_guard/警觉/backlash/sapped/snare/recoil/ ap_drain/gp_lose——ap_drain 按 A6 flat 1、gp_lose 按 A5 代理 2 计)。 - β 比值带判读与逐型净期望输出: β(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 # ============ 现行值链(出处见各注释;重跑按当期 .tres 更新) ============ D_REF = 4 # settlement.tres equivalence_ref_damage P_PERFECT = 200 # settlement.tres(percent,÷100 = ×2 双份交付) C_MIN, C_MAX = 24, 40 # reward.tres clear_blast power_min/max;期望口径 = 中点 32 AP_R = 8 # action_economy.tres ap_per_round DIG_COST = 1 # action_economy.tres dig_ap_cost IOTA = 0.88 # board_gen.tres inferability_target(判式 ι 代理) # 效果行值(status_effects.tres) 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) SPARK_AOE = 1 # 爆裂粉尘(全体存活敌) HEAL_MINOR = 2 # 急救敷料(Package B 第 2 轮) HEAL_BACKLASH = 6 # 反噬震荡(主角直伤) PIERCE_STRIKE = 2 # 穿刺弹(单目标克制直伤,必中全额) MAGIC_BOLT = 2 # 魔法矢(同上) PIERCE_SNARE = 8 # 穿刺陷阱(主角直伤) MAGIC_RECOIL = 8 # 魔法反噬(主角直伤) 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,合计 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} # β 比值带 [1.2, 2.5](u=3 登记态 1.17 微破下限=点名不强制回滚) BETA_LO, BETA_HI = 1.2, 2.5 # δ 旗溢价(形态 a 兑付溢价,δ=1.25 provisional ⇒ 兑付按同型正向 ×(1+δ)) DELTA = 0.25 # 板形(|M| 幸存雷 / |S| 安全格)双口径 # 名义 = density×(W×H−9) 初布值(参考板形口径,连续性参照) # 实测 = sim/board_stat_probe.gd 200 样本/行均值("先布后删"落地值,主流读数) # (实测值沿用 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)——整数量级实现口径(与机制同式:各型四舍五入取整后折算)。 条件二常设判读式:条件二 = 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 # 条件二(机制在位):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()