balance(m3-iter5-T3): 杠杆网格扫描+四级阶梯落档——配对种子10配置(OFAT六+C1/C2/C3+B0):L2可收带(C3类=岩浆1+plb0+卓尔100+percent4→普通L2 24%带缘/完美L2 56.2%入带);完美L1全网格89%钉死(三选一待用户);群战上探被unit_count_max域守卫封死;r_boss锚漂移登记(L2/L3≈0.33<域下限);对账件四项重跑记录(护栏B/挖掘不等式重立/sapped-heal当量/换算率锚复验)+刷新阈值提案;行值零变更待判读(U1+k+完美L1三选一)

This commit is contained in:
DKChan committed 2026-09-28 20:04:35 +08:00
1 parent e55dc1075d
commit 09862615e6
4 files changed
+243 -2

No files matched your search

@@ -120,6 +120,19 @@ MVP 行值并不逐式现算,而是按此式量级直填经切片验证过的
第三关口径(第三关内容批):L3 全部行值 provisional-pending-growth,上述各带对 L3 暂不适用——零成长基线下的红档属预期(主角成长侧前置 = GP+商店房批,已于 2026-09-20 落地:GP 掉落 + 商店房 + 格面金币),现行冒烟的首遇绿档断言按「成长代理档 atk+200 / hp+100」口径执行;正式通关率带与首遇绿档口径随玩家成长落地换装,归曲线调参批统一收带。
**判读口径同步(M-3 迭代 5 基线重测批,2026-09-28)**:通关率带的测量口径 = 冒险条件通关率(打通 k−1 关才到达第 k 关,balance_verifier 冒险段派生;单关直入口口径已随 2026-09-23 拍板退役)——带值沿用 2026-09-20 分带修正(普通档 L1 [35,55] / L2 [25,45]、完美档 [35,65];M-3 迭代 5 计划书 C4 冻结:改带=用户拍板)。上方行 115 的「带退役待重锚、重锚前只测不判」注记按本条同步理解:迭代 5 基线重测已按现行带对冒险条件口径判读(读数见 `design/qa/m3-iter5-baseline-2026-09-28.md`);是否在新口径上重取带值,归迭代 5 出口判读由用户拍板,本批不动带数字。
### 越带回滚阶梯(四级阶梯,2026-09-28 落档——自 acceptance-ap6-ac v1.0 §e 收编)
读数越带时的处置阶梯,粒度细→粗、爆炸半径小→大,**双向可用**(承伤偏低加深压力、承伤偏高放宽折扣):
1. **实现缺陷检查(AC 档位边界)**——先查双重乘算、档位映射反向等缺陷,对照掷点面 EV 减免读数定位,再谈调参;
2. **AC 档位值**——掷点折扣/暴击档位行值(读 `settlement.tres`);
3. **难度曲线行值加难**——本系统行值(血量锚走廊、变异 effect_value/percent_of_cells/per_level_bonus、群战数量、注入衰减等已登记杠杆位);
4. **行动点 6→4**——量程最大、爆炸半径最大(AP 已于压速批落 6,第四级启用即推翻压速批拍板,须用户裁决)。
四条边界:①「承伤偏高(减免过度)」败向先查实现缺陷再谈调参;②动用行值级或行动点级均使同种子历史坐标整体作废,须重立基线、另起验收批;③敌方 AC 正式值不进本链(归怪物设定批——M-3 迭代 5 T4 通道);④每次调参后全量重跑验收并在调参日志留联动检算记录(禁独立调参网络纪律)。
### 商店与 GP 经济杠杆:玩家侧供给 × 定价的第三族杠杆
GP(显示名「金币」)与商店房随 2026-09-20 GP+商店房批落地,给难度引入第三族玩家侧杠杆:**GP 供给 × 商品定价 = 入关属性参数**——供给或定价单边移动,玩家入关时的攻击 / 生命 / 护甲与通关率随之漂移,与血量锚走廊、变异 effect_value 同列进禁独立调参网络。
@@ -158,7 +171,7 @@ boss_hp ≈ round( Σ普通战斗敌方生命期望 × r_boss ) r_boss
|---|---|---|
| Σ普通战斗敌方生命期望 | 按数量区间期望逐行合计(区间中点),行值读敌人表 | 全关非 Boss 节点敌方生命合计;逐数闭合随调参批在调参日志留档 |
| r_boss | 域 [0.5, 1.1] | Boss 生命 = Σ × r_boss;Boss 行值读敌人表(provisional) |
| 加难走廊 | [1.1, 1.35] | 通关率压带的首选杠杆候选;扫描未执行,处 provisional-pending-scan(见「待办」) |
| 加难走廊 | [1.1, 1.35] | 通关率压带的首选杠杆候选;**扫描已执行(M-3 迭代 5,2026-09-28)**——域内取样(r_boss 0.8 档)对完美档 Boss 战无感(胜率 98% 血量加压打不到)、对普通档 −6pp;走廊段(>1.1,越域)未启用——启用即越域须登记(读数明细见 `design/qa/m3-iter5-lever-scan-2026-09-28.md`) |
Σ 的逐数闭合口径:数量走开战掷骰的区间期望(区间中点),教学位同样掷骰、按区间期望计入;各坐标行值一律读敌人表,本文不重复登记具体数值——防与配置双写失同步。
@@ -266,7 +279,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板
| 参数 | 取值域 / 口径 | 说明 |
|---|---|---|
| 血量锚比率 r_boss | [0.5, 1.1];加难走廊 [1.1, 1.35] 待扫描 | Boss 生命锚 |
| 血量锚比率 r_boss | [0.5, 1.1];加难走廊 [1.1, 1.35](扫描已执行,见「Boss 设计」节) | Boss 生命锚;**锚漂移登记(迭代 5 基线重测批)**:数值设计批 Boss 血轴拔高后 L2/L3 现值 r_boss≈0.33(全行集 Σ 口径)低于域下限 0.5——复算与是否收锚归迭代 5 出口判读 |
| 克制矩阵 | 克制 / 中性 / 被克三档加法修正(+1/0/−1 点),读 `settlement.tres` 甲效表 | 消费归[战斗结算](../战斗循环/战斗结算.md) |
| 完美排雷乘数 | 读表 | 调参权本文 |
| 当量参考敞口 | 读表 | 变更触发全量对账重跑 |
@@ -0,0 +1,81 @@
# M-3 迭代 5 杠杆网格扫描报告(T3)
- **日期**:2026-09-28
- **被测构建**:master @ 20533e3 + T1 基线(无行值改动——本报告全部读数为**补丁即跑即还原**的扫描读数,现行数据表零变更)
- **工具**:`tools/t3_lever_scan.py`(本批批内扫描入口——对 `variation.tres`/`enemy.tres` 打锚文本补丁 → 跑 `adventure_monte_carlo.gd` → git checkout 还原);原始逐配置读数 `sim-data/t3_scan_results.jsonl`(10 配置)
- **方法**:配对种子(全部配置同种子窗 73000,unique 逐局独立,N=100/策略/配置)——配置间差分 = 配对增量,消种子方差;判定带 = C4 冻结现行带(普通 L1 [35,55]/L2 [25,45]、完美 [35,65])
- **过程事故登记**:B0 首跑与 P2 并发执行致两者读到同一份补丁表(读数逐位相同=作废)——扫描配置禁并发的教训入账;B0 已单跑重测(本报告以重测值为准)
## 一、扫描网格与读数(N=100/策略,配对种子 73000)
### 配对基线 B0(现行表值)
| | 普通 L1 | 普通 L2 | 完美 L1 | 完美 L2 |
|---|---|---|---|---|
| B0 读数 | 50.0% | 4.0% | 89.0% | 15.7% |
| 现行带 | [35,55] ✓ | [25,45] ✗ | [35,65] ✗ | [35,65] ✗ |
### OFAT 单杠杆增量(对 B0 配对差分,单位 pp)
| 探针 | 杠杆位 | Δ普通L1 | Δ普通L2 | Δ完美L1 | Δ完美L2 | 定性 |
|---|---|---|---|---|---|---|
| P1 | 岩浆 effect_value 2→1 | 0 | **+14.0** | 0 | +13.5 | L2 减难·强 |
| P2 | per_level_bonus 2→0 | 0 | **+14.0** | 0 | +15.8 | L2/L3 减难·强(L3 0→21.4%) |
| P3 | L2 Boss 卓尔 130→100 | 0 | +4.0 | 0 | +5.6 | L2 减难·弱 |
| P4 | 荆棘 effect_value 1→2 | −2 | +0.2 | **−7** | −1.1 | L1 加难·弱 |
| P5 | L1 Boss 酋长 72→86(r_boss 0.67→0.80 域内) | −6 | +0.5 | −1 | −4.3 | 只咬普通档(完美 L1 Boss 胜率 98%,血量加压打不到它) |
| P6 | L1 群战上探(一伙/大地精 max 3→4) | — | — | — | — | **结构性不可用**:ConfigDB 跨表校验硬上限 unit_count_max 域 [unit_count, 3],抬上限=改校验域,超本批授权 |
### 组合配置
| 配置 | 普通L1 | 普通L2 | 完美L1 | 完美L2 | 判 |
|---|---|---|---|---|---|
| C1 = P1+P2 | 50.0 ✓ | 22.0 ✗(−3) | 89.0 ✗ | 43.8 ✓ | 完美 L2 入带 |
| C2 = C1+P4+P5(注册杠杆全开) | 41.0 ✓ | 22.0 ✗(−3) | **81.0 ✗** | 49.4 ✓ | 全网格完美 L1 下限 |
| C3 = C1+P3+P7(percent 5→4) | 50.0 ✓ | **24.0**(带缘 −1,±4.4 CI 内) | 89.0 ✗ | **56.2 ✓** | 3/4 入带最优解 |
| C3 侧效应 | L3 无带:普通 0→16.7%、完美 0→34.0%(plb0+percent4 使 L3 变异密度 9%→4%) | | | | L3 带外注意项 |
## 二、扫描结论
1. **完美档 L1 全网格不可达**:89.0% 在全部 L2 减难杠杆下零位移(P1/P2/P3/P7 均不触 L1 环节);L1 定向杠杆全部弱(荆棘 +1 = −7pp 上限、酋长 +14 血对完美无感、群战上探被校验域封死)——注册杠杆集内 81%(C2)即完美 L1 下限,距带 [35,65] 上缘差 16pp。**完美 L1 的强势来自 10×10 板形 × 完美画像挖掘效率 × 奖励经济学,不在任何已注册旋钮的量程内**。
2. **L2 双画像可收带**:C3 类组合(岩浆 2→1 + per_level_bonus 2→0 + 卓尔 130→100 + percent_of_cells 5→4)把普通 L2 送到带缘 24.0%(差 1pp,N=100 噪声带内)、完美 L2 56.2% 稳入带。
3. **L3 侧效应**:L2 减难杠杆同时大幅抬升 L3 通关率(完美 0→34%)——L3 无带不判,但 L3 行值 provisional-pending-growth 的再校准(灰矮人矿城血轴)在判读后若采纳 C3 类组合将需要跟进(另批或同批追加行,非本扫描范围)。
4. **工程发现**:r_boss 锚漂移——数值设计批 Boss 血轴拔高后,L2/L3 现值 r_boss≈0.33(Σ普通战生命期望=389/415,全行集口径)低于注册域 [0.5,1.1] 下限(L1 0.67 在域内);复算与是否收锚归出口判读。
## 三、伴生对账件重跑记录(随批义务)
### ① 清图支配性护栏 B 重跑 ✅(tools/clear_dominance_audit.py,现行 .tres 值链)
- L1 前段·实测(10×10 统一板):完美档 Δ_clear 首次翻正(+8.3/+5.5/+2.7,u=1/2/3)——棋盘统一批后完美档在前段板清图挖掘已过支配线;
- L1 后段·实测 / L2·实测:仍全线 ✗(完美档缺口 −6.6 ~ −34.2 当量)——缺口形态与 2026-09-19 基线记录同构(当期记录 L1≈24/L2≈45),板形统一收窄了前段、未翻转后段;
- 护栏 B(防钓鱼上界):D_ref=4 下 C=13 vs 上界 10(|S|min=50)越 1.3×,|S|min=60 带 ✓——**越线处置三选一仍挂用户**(登记债务,本批不动数字)。
### ② 挖掘风险不等式(重立记录)✅
现行惩罚链(八型批换装后):雷格负向=踩雷直伤(flat 主角单据)+群伤负向=警觉(敌方 AC +1 掷点折扣分布型);当量换算走效果档位对照表(flat E=表值;AC 轴=点数×5pp×D_ref=0.2 当量/次攻击)。重立结论:**风险端定价对收益端系统性不足的状态未闭合**(与清图支配性 L1 后段/L2 ✗ 区同源——挖掘收益端在板形统一与奖励密度放大后走强);修正位=雷格惩罚行值/负向权重池,**不在本批注册杠杆集**(属新杠杆授权),债务登记维持、行值不动。
### ③ heal 负向直伤 + 乏力 sapped 量级当量 ✅
- heal 负向直伤现行 power=1:当量换算表 flat 类 E=表值=1 = 0.25×D_ref(一次基准攻击的 1/4)——与荆棘 1/岩浆 2/踩雷直伤同处 flat 小整数档(C1 加法核一致),**当量自洽,无越带面**(该行值无注册带);2026-09-17 压缩批(−4→−1)的量级锚对账义务以本记录履行。
- 乏力 sapped(−25% 输出一拍):percent 类 E=|层数×行值|÷100×D_ref=1.0 当量/结算——与 flat 一档同量级,轴一致。**已知债(不在本批)**:sapped 经 hero_offense 池的乘区接线缺口(格面调研「sapped 死效果」修复报价)仍挂格面差异化批,量级当量不受其影响。
### ④ 换算率锚联动复验 ✅
6/9/1(meta.tres conversion)在 T1 verifier campaign 段实测驱动正常:注入逐档生效无断链、爬升曲线健康(完美档 ~21 局/普通档 ~36–51 局进稳态通关,检查点表值平移 +21/+38 随触发自动生效)。锚定时效注记:6/9/1 标定于 2026-09-23(L2 收紧后旧口径);本批 L2 若按 C3 类收带(变易),爬升将进一步加速——**是否重标归出口判读**(护甲行强条目纪律:重测须按解锁后参数实测=verifier campaign 段即实测面)。
### ⑤ 刷新经济阈值基线读数 ✅(T1 交付,阈值提案随判读锁)
基线(T1):完美档 1.95 次/局·弃图率 19%·每轮刷新率 ≈4.7%(2026-09-19 基线 0.23 次/局·≤0.6% 的 ~30 倍位移——弃图重摇已进完美画像策略核心);普通档全零。**阈值提案(判读锁)**:预警阈值=弃图率 >30% 或每轮刷新率 >10%(≈2× 现行基线带外报警);现行值记「高弃图常态」观察态。
## 四、判读待决(停机等待面)
本批行值**零变更**(扫描=补丁即还原)——收带投值(provisional→正式)卡两点:
1. **U1 真人局未到账**:k 系数(真人整关承伤中位 ÷ 模拟完美档中位 55.0,预警线 k<0.3)未合入——06「加难杠杆扫描」条目的判读门=真人批 k 系数。采集指引=07⑨(零天赋档 3–5 局,日志自动落盘)。
2. **完美档 L1 无解需用户裁决**(三选一,与 U1 无关、独立待拍):
- 甲:**新杠杆授权**——敌方攻击基线上探(acceptance-ap6-ac f① 候选中有、06 条目注册表未收)或 L1 专属加难内容(新杠杆,须走杠杆注册);
- 乙:**带修正**——完美档 L1 带上缘 65 上调(改带=用户拍板,C4 让位);
- 丙:**接受 89% 挂账**——完美画像定位为上界仪(非真人画像),其 L1 越带不判、优先保 L2 双画像收带(本扫描读数支持)。
3. C3 类组合(若判读采纳)的行值清单:`variation.tres` 岩浆 effect_value 2→1、per_level_bonus 2→0、percent_of_cells 5→4;`enemy.tres` (2,9) 卓尔 hp 130→100;伴随义务=registry 同步 + L2 池复验(T4 AC 投值前先锁本组合,防两轴混淆归因)+ 小样 20 局→全量确认 + 侧效应 L3 记录。
> 扫描完成即 T3 机器面全毕;判读=停机点(计划书 §9-U1 等待 + 完美 L1 三选一)。等待期间 T4(AC 投值)/T5(节点图生成,实施门=调参收带后)按串行纪律顺延。
+10
View File
@@ -0,0 +1,10 @@
{"config": "P1_magma1", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [50, 100, 50.0], "L2": [9, 50, 18.0], "L3": [0, 9, 0.0]}, "perfect": {"n": 100, "L1": [89, 100, 89.0], "L2": [26, 89, 29.2], "L3": [1, 26, 3.8]}}}
{"config": "P3_drider100", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [50, 100, 50.0], "L2": [4, 50, 8.0], "L3": [0, 4, 0.0]}, "perfect": {"n": 100, "L1": [89, 100, 89.0], "L2": [19, 89, 21.3], "L3": [0, 19, 0.0]}}}
{"config": "P4_thorn2", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [48, 100, 48.0], "L2": [2, 48, 4.2], "L3": [0, 2, 0.0]}, "perfect": {"n": 100, "L1": [82, 100, 82.0], "L2": [12, 82, 14.6], "L3": [0, 12, 0.0]}}}
{"config": "P5_chief86", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [44, 100, 44.0], "L2": [2, 44, 4.5], "L3": [0, 2, 0.0]}, "perfect": {"n": 100, "L1": [88, 100, 88.0], "L2": [10, 88, 11.4], "L3": [0, 10, 0.0]}}}
{"config": "P6_L1swarm", "n": 100, "seed0": 73000, "readings": {"normal": null, "perfect": null}}
{"config": "P2_plb0", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [50, 100, 50.0], "L2": [9, 50, 18.0], "L3": [0, 9, 0.0]}, "perfect": {"n": 100, "L1": [89, 100, 89.0], "L2": [28, 89, 31.5], "L3": [6, 28, 21.4]}}}
{"config": "P1_magma1+P2_plb0", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [50, 100, 50.0], "L2": [11, 50, 22.0], "L3": [0, 11, 0.0]}, "perfect": {"n": 100, "L1": [89, 100, 89.0], "L2": [39, 89, 43.8], "L3": [8, 39, 20.5]}}}
{"config": "P1_magma1+P2_plb0+P4_thorn2+P5_chief86", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [41, 100, 41.0], "L2": [9, 41, 22.0], "L3": [0, 9, 0.0]}, "perfect": {"n": 100, "L1": [81, 100, 81.0], "L2": [40, 81, 49.4], "L3": [9, 40, 22.5]}}}
{"config": "B0_none", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [50, 100, 50.0], "L2": [2, 50, 4.0], "L3": [0, 2, 0.0]}, "perfect": {"n": 100, "L1": [89, 100, 89.0], "L2": [14, 89, 15.7], "L3": [0, 14, 0.0]}}}
{"config": "P1_magma1+P2_plb0+P3_drider100+P7_percent4", "n": 100, "seed0": 73000, "readings": {"normal": {"n": 100, "L1": [50, 100, 50.0], "L2": [12, 50, 24.0], "L3": [2, 12, 16.7]}, "perfect": {"n": 100, "L1": [89, 100, 89.0], "L2": [50, 89, 56.2], "L3": [17, 50, 34.0]}}}
+137
View File
@@ -0,0 +1,137 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""T3 杠杆网格扫描驱动(M-3 迭代 5)——临时批内工具,批末评估去留。
用法:python tools/t3_lever_scan.py <config名> [--n 100] [--seed0 73000]
流程:对 worktree 数据表打补丁 → 跑 adventure_monte_carlo.gd(N/策略,unique 逐局独立种子)
→ stdout RUNSUM 解析成逐关条件通关率 → git checkout 还原被改表(无论成败)。
补丁全部按锚文本定位(display_name/variant_id 上下文),打不上即 FAIL 不静默。
"""
import json
import re
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
GODOT = r"D:\code\godot\Godot_v4.7.2-stable_win64_console.exe"
VAR = ROOT / "game" / "data" / "tables" / "variation.tres"
ENEMY = ROOT / "game" / "data" / "tables" / "enemy.tres"
# 补丁集:config 名 → [(文件, 锚正则, 替换模板, 说明)]
PATCHES = {
"P1_magma1": [(VAR, r'("variant_id": "magma"[\s\S]{0,200}?"effect_value": )2', r'\g<1>1', "岩浆 2→1")],
"P2_plb0": [(VAR, r"(per_level_bonus = )2", r"\g<1>0", "per_level_bonus 2→0")],
"P3_drider100": [(ENEMY, r'("enemy_id": "drider"[\s\S]{0,400}?"hp": )130', r'\g<1>100', "L2 Boss 卓尔 130→100")],
"P4_thorn2": [(VAR, r'("variant_id": "thorn"[\s\S]{0,200}?"effect_value": )1', r'\g<1>2', "荆棘 1→2")],
"P5_chief86": [(ENEMY, r'("enemy_id": "ogre_chief"[\s\S]{0,400}?"hp": )72', r'\g<1>86', "L1 Boss 酋长 72→86")],
"P7_percent4": [(VAR, r"(percent_of_cells = )5", r"\g<1>4", "percent_of_cells 5→4")],
"P6_L1swarm": [
(ENEMY, r'("display_name": "地精一伙"[\s\S]{0,200}?"unit_count_max": )3', r'\g<1>4', "L1 d1 一伙 max 3→4"),
(ENEMY, r'("display_name": "大地精"[\s\S]{0,200}?"unit_count_max": )3', r'\g<1>4', "L1 d3 大地精 max 3→4"),
],
}
def apply_patches(name):
if name == "B0_none":
print("[scan] 补丁生效:B0_none(零补丁配对基线)")
return True
edits = PATCHES.get(name)
if edits is None:
# 组合:P1+P2+P3 形如 "C_magma+plb+boss"
parts = [p for p in name.split("+") if p in PATCHES]
if not parts:
print(f"[scan] 未知 config:{name}")
return False
edits = [e for p in parts for e in PATCHES[p]]
touched = {}
try:
for path, pat, rep, desc in edits:
txt = path.read_text(encoding="utf-8")
new, n = re.subn(pat, rep, txt)
if n != 1:
print(f"[scan] FAIL 补丁锚不唯一(命中 {n}):{desc}")
return False
if path not in touched:
touched[path] = txt
path.write_text(new, encoding="utf-8")
print(f"[scan] 补丁生效:{desc}")
return True
finally:
pass # 还原统一由 restore() 做——调用方跑完再调
def restore():
for f in (VAR, ENEMY):
subprocess.run(["git", "checkout", "--", str(f.relative_to(ROOT))], cwd=ROOT,
capture_output=True, text=True)
print("[scan] 表已还原(git checkout)")
def run_mc(n, seed0):
cmd = [GODOT, "--headless", "--path", str(ROOT / "game"), "--script",
"res://smoke/adventure_monte_carlo.gd", "--", str(n), str(seed0), "both", "min"]
proc = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8",
errors="replace", timeout=3600)
rows = {"normal": [], "perfect": []}
for line in (proc.stdout or "").splitlines():
if line.startswith("RUNSUM "):
r = json.loads(line[7:])
rows[r["policy"]].append(r)
return rows
def readings(rows):
out = {}
for pol, rs in rows.items():
n = len(rs)
if n == 0:
out[pol] = None
continue
d = {"n": n}
for k in (1, 2, 3):
reached = sum(1 for r in rs if r["levels_cleared"] >= k - 1)
passed = sum(1 for r in rs if r["levels_cleared"] >= k)
d[f"L{k}"] = (passed, reached, round(100 * passed / reached, 1) if reached else None)
out[pol] = d
return out
def main():
args = sys.argv[1:]
if not args:
print(__doc__)
return 2
name = args[0]
n = 100
seed0 = 73000
for i, a in enumerate(args):
if a == "--n" and i + 1 < len(args):
n = int(args[i + 1])
if a == "--seed0" and i + 1 < len(args):
seed0 = int(args[i + 1])
print(f"[scan] === config {name} · N={n}/策略 · seed0={seed0} ===")
if not apply_patches(name):
restore()
return 1
try:
rows = run_mc(n, seed0)
finally:
restore()
rd = readings(rows)
for pol in ("normal", "perfect"):
d = rd.get(pol)
if not d:
print(f"[scan] {pol}: 无 RUNSUM(采集异常)")
continue
cells = " · ".join(
f"L{k} {d[f'L{k}'][2]}% ({d[f'L{k}'][0]}/{d[f'L{k}'][1]})" for k in (1, 2, 3))
print(f"[scan] {pol}: {cells}")
print("[scan] RESULTJSON " + json.dumps({"config": name, "n": n, "seed0": seed0, "readings": rd},
ensure_ascii=False))
return 0
if __name__ == "__main__":
sys.exit(main())