feat(卡② T7-V12): 同种子复放比对器 parity_compare.py + 三组判读记录
--mode parity(off 组整条逐位相等)/--mode input-parity(formed/rules 输入面八字段+顶层字段集恒等+局数种子集一致);
退出码 0/1/2,字段集从基线推导。判读结论:off 组 base==post 逐字节一致(bf084ef3…,确定性零漂移);
formed/rules input-parity PASS(输出面差=已定性预期行为变更);rules≠off 0 局相同(分组非空转)。
基线=master 码+采集器修复重采(卡片 f75acc15 基线因卡① 改 game/ 作废,据 T0 重采,哈希 2d3d4247/0fcbcb26 复现卡片在册值)。
This commit is contained in:
1 parent
430f97f071
commit
a9d5ac13db
1 file changed
+68
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""V12 同种子复放比对器(卡② 效果引擎无状态化批):解析两次 MC 采集的 RUNSUM 行按 seed 配对判读。
|
||||
两判据模式——parity:整条记录逐位相等(off 组,未受影响路径须透明);
|
||||
input-parity:输入面八字段 + 顶层字段集恒等、种子集与局数一致(formed/rules 组,输出面允许 RNG 级联位移)。
|
||||
退出码 0 绿 / 1 红 / 2 用法或解析错。字段集从基线文件推导,禁硬编码。"""
|
||||
import sys, json, argparse
|
||||
|
||||
INPUT_KEYS = ["policy", "seed", "atk_pct", "hp_pct", "route", "attune", "equipped", "feat_mode"]
|
||||
|
||||
|
||||
def load(path):
|
||||
recs = {}
|
||||
with open(path, encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line.startswith("RUNSUM "):
|
||||
continue
|
||||
try:
|
||||
d = json.loads(line[len("RUNSUM "):])
|
||||
except json.JSONDecodeError:
|
||||
print("解析失败行:", line[:80])
|
||||
sys.exit(2)
|
||||
recs[d.get("seed")] = d
|
||||
return recs
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--mode", choices=["parity", "input-parity"], required=True)
|
||||
ap.add_argument("--base", required=True)
|
||||
ap.add_argument("--post", required=True)
|
||||
ap.add_argument("--expect", type=int, required=True)
|
||||
a = ap.parse_args()
|
||||
base, post = load(a.base), load(a.post)
|
||||
if len(base) != a.expect or len(post) != a.expect:
|
||||
print("局数不符:base=%d post=%d expect=%d" % (len(base), len(post), a.expect))
|
||||
return 1
|
||||
if set(base) != set(post):
|
||||
print("种子集不一致")
|
||||
return 1
|
||||
red = False
|
||||
if a.mode == "parity":
|
||||
diff = [s for s in base if base[s] != post[s]]
|
||||
if diff:
|
||||
red = True
|
||||
print("off 组逐位差异 %d 局: %s" % (len(diff), diff[:10]))
|
||||
for s in diff[:3]:
|
||||
k = [kk for kk in base[s] if base[s].get(kk) != post[s].get(kk)]
|
||||
print(" seed", s, "差异字段:", k)
|
||||
else:
|
||||
bkeys = set(next(iter(base.values())).keys())
|
||||
pkeys = set(next(iter(post.values())).keys())
|
||||
if bkeys != pkeys:
|
||||
red = True
|
||||
print("顶层字段集不一致 base-p=%s post-b=%s" % (bkeys - pkeys, pkeys - bkeys))
|
||||
for s in base:
|
||||
for kk in INPUT_KEYS:
|
||||
if base[s].get(kk) != post[s].get(kk):
|
||||
red = True
|
||||
print("输入面字段 %s 在 seed %s 不一致: %r vs %r" % (kk, s, base[s].get(kk), post[s].get(kk)))
|
||||
# levels_cleared 直方图仅报告(方向不作判据)
|
||||
lc = post[s].get("levels_cleared") if post else None
|
||||
print("判读:%s" % ("FAIL" if red else "PASS"))
|
||||
return 1 if red else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user