test(迭代35卡②T3 V3 补口+报告对照表): 大岔口分区域兑付断言组落地(卡片 V3 是本卡 §8 唯一无机检断言的验收点,前口漏挂——本轮补)——level_shop_economy 新增 _smoke_multi_terminal_settlement 五条:L2 现行图 Boss 终点两颗以上、min/max 两轴各自收在本路终点 Boss(末句柄 6/11 互异且都属图 Boss 集,result=victory)、区域隔离(min 路不含 max 终点、反之亦然)、任一 Boss 胜即本关收束 level_finished 恰一次且载荷 result=victory·node_id=该终点句柄(真实 runner.start_level+pick_next_node+_autoplay_battle 全程驱动,兑付停点走 continue_after_node 与 _drive_level 同口径);宿主 176→181 条全绿。实现报告补 §二·十三 实际对照表(卡片 §8.2 八行逐行给文件:行/真实入口/撤销证明对应 M1-M7 与 T1/覆盖批变异)与终版宿主读数

This commit is contained in:
DKChan committed 2026-10-24 19:45:59 +08:00
1 parent 3461e83bec
commit 4ed53651ce
2 files changed
+70

No files matched your search

@@ -248,6 +248,7 @@ func _init() -> void:
_smoke_gp_escrow()
_smoke_shop_room()
_smoke_shop_graph()
_smoke_multi_terminal_settlement()
_smoke_shop_pool()
_smoke_generated_coverage()
quit(Kit.finish("level_shop_economy_test"))
@@ -1151,6 +1152,60 @@ func _smoke_shop_graph() -> void:
Kit.check("L1 现行图跨表覆盖(战斗/Boss 节点 %d 颗非空·敌侧违例 %d·板侧违例 %d)" % [int(l1_cov["nodes"]), int(l1_cov["enemy_bad"]), int(l1_cov["board_bad"])],
int(l1_cov["nodes"]) >= 1 and int(l1_cov["enemy_bad"]) == 0 and int(l1_cov["board_bad"]) == 0)
# ---- ⑥ 大岔口分区域兑付(V3——多终点图走哪条路决定打谁,任一 Boss 胜即收束恰一次)----
func _smoke_multi_terminal_settlement() -> void:
print("--- 大岔口分区域兑付(L2 两轴各打各的终点)---")
var autoplay = load("res://sim/level_autoplay.gd")
var nodes: Array = _generated_graph(2, 42).get("nodes", [])
var boss_ids := _ids_of_type(nodes, "boss")
Kit.check("L2 现行图为多终点(Boss 终点 %s 两颗以上——大岔口承载面)" % str(boss_ids), boss_ids.size() >= 2)
var run_min: Dictionary = autoplay.run_level(_db, 42, 2, 400, 300, false, null, "normal", "min")
var run_max: Dictionary = autoplay.run_level(_db, 42, 2, 400, 300, false, null, "normal", "max")
var min_vis: Array = run_min.get("visited_ids", []) as Array
var max_vis: Array = run_max.get("visited_ids", []) as Array
var min_last := -1
var max_last := -1
if not min_vis.is_empty():
min_last = int(min_vis[min_vis.size() - 1])
if not max_vis.is_empty():
max_last = int(max_vis[max_vis.size() - 1])
# 走哪条路决定打谁:两路各自收在本路终点 Boss 上且互不相同;本关收束 result=victory
Kit.check("L2 min/max 两路各打进各自终点 Boss(末句柄 %d / %d 互异且都在图 Boss 集 %s 内;两路 result=%s/%s)" % [min_last, max_last, str(boss_ids), String(run_min.get("result", "")), String(run_max.get("result", ""))],
String(run_min.get("result", "")) == "victory" and String(run_max.get("result", "")) == "victory"
and boss_ids.has(min_last) and boss_ids.has(max_last) and min_last != max_last)
# 不误兑付:另一颗 Boss 不在本路已到序里(走 A 区不误兑付 B 区 Boss)
Kit.check("min 路未到 max 终点 %d、max 路未到 min 终点 %d(区域隔离——走 A 区不误兑付 B 区 Boss)" % [max_last, min_last],
not min_vis.has(max_last) and not max_vis.has(min_last))
# 任一 Boss 胜=本关收束恰一次(level_finished 一次·载荷 result=victory 且 node_id=该终点句柄)
var fin := {"count": 0, "payload": {}}
var runner = load("res://core/level_runner.gd").new(_db, _fresh_rng(42))
runner.set_hero_override(400, 300) # 满配档——全程驱动须打到 Boss 才收束
runner.level_finished.connect(func(p): fin["count"] = int(fin["count"]) + 1; fin["payload"] = p)
Kit.check("L2 全程驱动启动受理", runner.start_level(2, 42))
var st_drive := _battle_st("normal")
var guard := 40
while guard > 0 and int(fin["count"]) == 0:
guard -= 1
if runner.awaiting_choice():
var ids: Array = runner.next_candidate_ids()
if ids.is_empty():
break
runner.pick_next_node(int(ids[ids.size() - 1]))
continue
var b = runner.current_battle()
if b == null:
# 兑付停点(休整/商店/奖励直通)——先确认继续再回到选路,与 _drive_level 同口径
if not runner.continue_after_node():
break
continue
var inner := 40
while inner > 0 and runner.current_battle() == b:
inner -= 1
autoplay._autoplay_battle(runner, b, st_drive, null)
var payload: Dictionary = fin["payload"]
Kit.check("任一 Boss 胜即本关收束恰一次(count=%d·载荷 result=%s·node_id=%s 在图 Boss 集 %s 内)" % [int(fin["count"]), String(payload.get("result", "")), str(payload.get("node_id", -1)), str(boss_ids)],
int(fin["count"]) == 1 and String(payload.get("result", "")) == "victory"
and boss_ids.has(int(payload.get("node_id", -1))))
# 现行图全路径穿店恰一(性质③在单图上的整体读数)
func _paths_all_one_shop(nodes: Array) -> bool:
@@ -140,6 +140,21 @@
卡片 §8 变异清单九条的落位:V1 两条(T1 已录)、V11 两条(覆盖批已录)、V2/V5×2/V6/V7/V8/V9 共六条(本表 M1–M7,V5 拆两条)。
## 二·十三 实际对照表(卡片 §8.2 八行的落地坐标;审计第 1 件按此逐行核)
| 需求点 | 测试落点(文件:行/尾缀) | 真实入口 | 撤销或变异证明 |
|---|---|---|---|
| 加载校验四检+良构 | `game/tests/unit/core/level_table_validate_test.gd`(17 条,〔v1〕)+起关拒绝段 `game/core/level_runner.gd:308-312` | `LevelRunner.start_level_external`(违规图返回 false) | T1 四条注入见红(§二·五):终点恒 Boss 判据注释、无环判据短路等 |
| 行进语义(多入口/大岔口/多 Boss/单链) | `node_map_templates_test.gd:60-66`〔v2〕;`level_shop_economy_test.gd:1157-1216`(V3 段:多终点图、两路各收本路 Boss、区域隔离、收束恰一次);`level_shop_economy_test.gd:339`〔v4〕(L1 终点恰一)+`:632`(L3 入口数=`entry_count`、终点数=`exit_count`) | `LevelRunner.start_level_external`/`start_level`+`pick_next_node`/`sim/level_autoplay.run_level`(route=min/max 两轴全程驱动) | M1(候选写死单入口)→〔v2〕红 |
| 商店编排三条性质 | `level_shop_economy_test.gd:1129-1133`〔v5〕(扫描面非空+性质①②③,60 图/1413 路径读数)+`:1000-1010` 行进面 | 生成图逐节点解析+`runner` 行进到店 | M2(终点前驱非店)→性质①红;M3(加第二家店)→性质②③红 |
| 生成图覆盖+多终点 Boss 带互异 | `level_shop_economy_test.gd:259-306`〔v11〕+`adventure_feats_test.gd:111-131`〔fv24〕 | `ConfigDB.resolve_enemy_rowset`/`resolve_board_gen` 真实消费链 | 覆盖批两条注入已录(Boss 带并单带、删顶带);〔fv24〕判据与〔v11〕同源单点 |
| 定位信息两样(关卡序号+节点深度) | `adventure_feats_test.gd:159-166`〔v6〕(读 `BattleOrchestrator.encounter`) | 真实进战入口 `_drive_to_pref`→`pick_next_node`→`begin_battle` | M4(enc `node_depth` 取句柄)→〔v6〕红 |
| 确定性承载+旧断点代差 | `node_map_templates_test.gd:44-95`〔v7〕〔v8〕;`breakpoint_resume_test.gd:157-183`〔v7〕〔v8〕〔v9〕 | `NodeMapGenerator.generate`/`AdventureRunner.start_adventure`/`resume_adventure`(真实快照写手 `SaveManager`) | M5(产图改计数器流)→〔v7〕红;M6(缺代差键放行)→〔v8〕红 |
| 15 张模板清理 | `node_map_templates_test.gd:91-96`〔v9〕+件核 grep(全仓零 `templates`/`first_script`/`template_pick`/`active_template`) | `ConfigDB.level_row` 表读面 | M7(表内偷留 `templates` 键)→〔v9〕红 |
| 反哺点清单(非行为改动) | `reports/iter35-卡②-反哺点-2026-10-24.md` 十条落点 | T4 产出物件核 | 缺任一落点=V10 件核红(本文件 §三·一 目检两条同批登记) |
宿主读数(终版):`level_shop_economy_test` 181 条、`node_map_templates_test` 21 条、`adventure_feats_test` 138 条、`breakpoint_resume_test` 56 条、`level_table_validate_test` 17 条。
## 三·一 实机目检总清单(真人判断项,登记即完成义务,不作为合回前置)
| # | 观测项 | 真实入口 | 期望看到什么 | 本批机检已覆盖的部分 |