From 7077a04d52ebcf6dd152145d9761880df910e1e1 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Fri, 23 Oct 2026 01:54:24 +0800 Subject: [PATCH] =?UTF-8?q?test(=E8=BF=81=E7=A7=BB):=20=E6=89=B9=20B=20?= =?UTF-8?q?=E6=B3=A2=201=20G3=20=E5=A5=971=20=E6=A0=BC=E8=BE=B9=E5=85=AC?= =?UTF-8?q?=E5=BC=8F=E4=B8=A4=E6=9D=A1=E8=BF=81=E5=85=A5=20board=5Fgen=5Fr?= =?UTF-8?q?eward=5Ftest.gd=E2=80=94=E2=80=94=E6=96=B0=E5=AE=BF=E4=B8=BB?= =?UTF-8?q?=E8=90=BD=E4=BD=8D=EF=BC=8Bmanifest=20=E7=99=BB=E8=AE=B0?= =?UTF-8?q?=EF=BC=8B=E5=89=AA=E5=88=87=E6=8C=82=E8=BD=BD=E7=BB=BF=EF=BC=8B?= =?UTF-8?q?=E6=8C=89=E6=9D=A1=E5=8F=98=E5=BC=82=202/2=20=E9=AA=8C=E7=BA=A2?= =?UTF-8?q?=EF=BC=88=E9=97=B4=E8=B7=9D=E9=A1=B9=E5=88=A0=E9=99=A4=E4=B8=8E?= =?UTF-8?q?=E9=92=B3=E5=88=B6=E5=B8=A6=E5=87=BA=E5=B8=A6=E5=90=84=E7=BA=A2?= =?UTF-8?q?=E5=94=AF=E4=B8=80=EF=BC=89=EF=BC=9Bsmoke=5Fall.gd=20=E5=90=8C?= =?UTF-8?q?=E6=89=B9=E5=88=A0=E5=87=BD=E6=95=B0=EF=BC=8C=5Fmk=5Fstream=20?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=20helper=20=E5=8F=8C=E4=BB=BD=E8=BF=87?= =?UTF-8?q?=E6=B8=A1=EF=BC=88G11=20=E4=BB=8D=E6=B6=88=E8=B4=B9=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/smoke/smoke_all.gd | 20 ------ game/tests/run_all.gd | 1 + game/tests/unit/core/board_gen_reward_test.gd | 66 +++++++++++++++++++ reports/批B-断言迁移账本-2026-10-22.md | 7 ++ 4 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 game/tests/unit/core/board_gen_reward_test.gd diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index 27565dce..8b146062 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -1064,26 +1064,6 @@ func _adv_st() -> Dictionary: -# ---- 战斗屏棋盘布局·格边长公式回归(真人试玩 bug⑥:L2 12×12 板下缘被裁约 1/6 格高—— -# 公式 N×cell ≤ 可用高−12 必须计入 (N−1)×2px 网格间距,否则网格实高溢出被 clip_contents 裁掉; -# 现公式 = 计入间距 + 垂直预留 24px〔上 12/下 12——底部不贴 D 区边框〕)---- -func _smoke_layout_cell_formula() -> void: - print("--- 棋盘布局格边长公式(底部预留回归)---") - var board_generator = load("res://core/board_generator.gd").new() - var board_view = load("res://presentation/views/board_view.gd").new() - for L in [1, 2]: - var b = board_generator.generate(L, 0, _mk_stream("board_gen", 555), _db) - board_view.rebuild(b, null) - var avail := Vector2(1036, 460) # 受约束 D 区可用面积样本(1280×800 档量级——用户实测裁切场景) - board_view.set_cell_area(avail) - var n: int = maxi(b.width, b.height) - var cell: float = board_view.get("_cell") - var grid_h := n * int(cell) + (n - 1) * 2 - check(grid_h <= int(avail.y) - 24, "L%d %dx%d 板网格高 %d ≤ 可用高 %d − 预留 24(格边 %dpx——下缘不贴边不裁切)" % [L, b.width, b.height, grid_h, int(avail.y), int(cell)]) - check(cell >= 26.0 and cell <= 46.0, "L%d 格边在 26–46 档内(%dpx)" % [L, int(cell)]) - board_view.free() - - # ---- 未开格类型微光·数据侧断言(V1 作用集恒等/V2 九型归组封闭/V7 零玩法写入)---- # 夹具纪律:身份回调形状与 reward_economy.query_identity 同构({reward_id, cell_type, tier}); # 位点覆盖表 _glow_type_overrides(Vector2i → cell_type)+封锁集 _glow_blocked(Vector2i → true, diff --git a/game/tests/run_all.gd b/game/tests/run_all.gd index f1e4272a..dfab90ab 100644 --- a/game/tests/run_all.gd +++ b/game/tests/run_all.gd @@ -79,6 +79,7 @@ func _suites() -> Array: {"path": "res://tests/integration/save_rng_roundtrip_test.gd", "expect": 0}, # 存档⇄RNG 快照往返(SaveManager 迁移链 × 断点消费 × RNG 续跑 × 停点态确定性) # ---- core 四件与呈现层两件的直接单测 ---- {"path": "res://tests/unit/core/board_generator_test.gd", "expect": 0}, # 棋盘生成(尺寸合表/数字=八邻雷数/同种子逐位一致/可推理自洽) + {"path": "res://tests/unit/core/board_gen_reward_test.gd", "expect": 0}, # 棋盘生成与地图战斗资源宿主(格边长公式/资源身份面/生成器三分出口与 r0 闸/伤害量值区间——批 B 自 smoke_all 迁入) {"path": "res://tests/unit/core/minesweeper_rules_test.gd", "expect": 0}, # 排雷规则(装板不变量/挖的 face 规则/揭示推进/封印/目录外拒) {"path": "res://tests/unit/core/config_db_resolver_test.gd", "expect": 0}, # 配置解析(ceil 偏难语义/行集行序/难度 clamp) {"path": "res://tests/unit/core/config_db_cross_validator_test.gd", "expect": 0}, # 跨表校验(正向零错/悬空 skill_id/side 反向) diff --git a/game/tests/unit/core/board_gen_reward_test.gd b/game/tests/unit/core/board_gen_reward_test.gd new file mode 100644 index 00000000..5fd3d340 --- /dev/null +++ b/game/tests/unit/core/board_gen_reward_test.gd @@ -0,0 +1,66 @@ +# tests/unit/core/board_gen_reward_test.gd — 棋盘生成与地图战斗资源单元测试宿主 +# 断言面 = 四套(批 B 断言迁移自 smoke_all.gd,G3 施工组): +# 棋盘布局格边长公式(board_view 格尺寸——下缘预留回归,真人试玩 bug⑥) +# 地图战斗资源·身份面(roll 恰一次 / 五型封闭 / 幂等 / 清图批尾 / 退役闭合) +# 棋盘生成器(行解析 / 可清性 / 合法性 / 出图验收 / 三分出口 / 确定性 / r0 闸) +# 地图战斗资源·伤害量值区间(中点锚 / 域内 / 流动 / 定值不受扰) +# 协议照单元侧惯例:extends SceneTree+Kit.check 主通道;--script 模式无 autoload, +# ConfigDB/RngService 显式实例化构造注入(统一流 master 种子 42 沿源); +# 表加载失败不中止(沿被迁断言面的源语义——诊断在此展开,表值变异的红由具体断言落,承 G2 同款)。 +# 运行:godot --headless --path game --script res://tests/unit/core/board_gen_reward_test.gd +extends SceneTree + +const Kit := preload("res://tests/unit/test_kit.gd") +const ConfigDBScript := preload("res://core/config_db.gd") + +var _db +var _rng + + +func _init() -> void: + _db = ConfigDBScript.new() + # 表加载失败不中止(承 G2 同款:表损坏的红落在具体断言上—— + # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) + var load_ok: bool = _db.load_tables("res://data/tables", true) + if not load_ok: + push_error("[board_gen_reward_test] 表加载返回失败——诊断如下(红由具体断言落)") + for d in _db.diagnostics(): + if d.severity == "error" or d.severity == "fatal": + push_error(" [%s] %s: %s" % [d.severity, d.category, d.message]) + _rng = load("res://core/rng_service.gd").new() + _rng.set_master_seed(42) + # 套执行序沿源编排序 + _smoke_layout_cell_formula() + quit(Kit.finish("board_gen_reward_test")) + + +# ---- 隔离夹具 ---- + +# 定域流桩(scope 派生种子——derive_at 纯函数,与取号计数器状态无关) +func _mk_stream(stream_name: String, scope: int) -> RandomNumberGenerator: + # stream_name = 调用点自述标签(不参与派生),保留参数零改调用方 + var rg := RandomNumberGenerator.new() + rg.seed = _rng.derive_at(scope) + return rg + + +# ---- 战斗屏棋盘布局·格边长公式回归(真人试玩 bug⑥:L2 12×12 板下缘被裁约 1/6 格高—— +# 公式 N×cell ≤ 可用高−12 必须计入 (N−1)×2px 网格间距,否则网格实高溢出被 clip_contents 裁掉; +# 现公式 = 计入间距 + 垂直预留 24px〔上 12/下 12——底部不贴 D 区边框〕)---- +func _smoke_layout_cell_formula() -> void: + print("--- 棋盘布局格边长公式(底部预留回归)---") + var board_generator = load("res://core/board_generator.gd").new() + var board_view = load("res://presentation/views/board_view.gd").new() + for L in [1, 2]: + var b = board_generator.generate(L, 0, _mk_stream("board_gen", 555), _db) + board_view.rebuild(b, null) + var avail := Vector2(1036, 460) # 受约束 D 区可用面积样本(1280×800 档量级——用户实测裁切场景) + board_view.set_cell_area(avail) + var n: int = maxi(b.width, b.height) + var cell: float = board_view.get("_cell") + var grid_h := n * int(cell) + (n - 1) * 2 + Kit.check("L%d %dx%d 板网格高 %d ≤ 可用高 %d − 预留 24(格边 %dpx——下缘不贴边不裁切)" % [L, b.width, b.height, grid_h, int(avail.y), int(cell)], + grid_h <= int(avail.y) - 24) + Kit.check("L%d 格边在 26–46 档内(%dpx)" % [L, int(cell)], + cell >= 26.0 and cell <= 46.0) + board_view.free() diff --git a/reports/批B-断言迁移账本-2026-10-22.md b/reports/批B-断言迁移账本-2026-10-22.md index 6337f3bf..212fbf80 100644 --- a/reports/批B-断言迁移账本-2026-10-22.md +++ b/reports/批B-断言迁移账本-2026-10-22.md @@ -262,6 +262,13 @@ 施工发现(供后续组参考,接 G1 序号):④ 共享 helper 迁移形态=宿主复制+smoke_all.gd 原地保留双份(残余套仍消费;本波各组禁从 smoke_all.gd 删共享 helper,收尾批统一去重);⑤ 表值变异若触发表内 validate(配额锚/AC 带宽/互锁等),在「夹具 load 失败不中止」形态下红自然落到断言,无需两点变异;仅当变异被断言外机制吞掉(round 舍入/不变式未破/执行序不可达)才换变异点,并在账本记明无效变异首试;⑥ 宿主 fixture 与现役单元「load 失败即退」惯例不同(沿源语义不中止),后续 data_config 侧新宿主按各自断言面对齐源形态选择。 +**G3 单元·棋盘生成与资源 → game/tests/unit/core/board_gen_reward_test.gd:四套 39 条逐套原子提交(本组起组内按套提交)。** +挂载终态=宿主 `_init` 自建 `_db`(ConfigDB 构造注入,`load_tables(..., true)` 失败不中止承 G2 同款)+`_rng`(RngService master 种子 42 沿源,全新取号计数);套执行序沿源编排序(layout_cell_formula→reward_identity→board_generator→power_interval)。helper 随迁:`_mk_stream`(实例法,依赖 `_rng`;smoke_all.gd 原件保留——G11 `_smoke_type_glow` 仍消费)+`_board_dump`/`_row_power`(实例法,依赖 `_db`)+内嵌类 `_BoardRowStub`;`BoardData`/`RewardTable` 全局 class_name 裸用(--script 模式全局类在册,G2 宿主同先例)。manifest 登记随首套 commit。 + +逐套变异记账(每条独立一轮:改坏→跑新宿主→红→`git checkout` 还原→`git status` 清洁确认): + +- `_smoke_layout_cell_formula`(2 条):2/2 验红。变异点——board_view.gd:233 删 `- float((n - 1) * sep)` 格间距项(bug⑥ 原缺陷形态;红唯一两条迭代齐红 L1 438/L2 442 > 436,档内条保持绿);board_view.gd:234 clamp 上界 46→25(该条守面=钳制带本体——夹具板实测格边 41/33 为带内值,带内改界不红,改界出带方验红;红唯一两条迭代齐红 25px < 26,网格高条保持绿)。 + ## 十、支援线 9 项待裁闭合(2026-10-22 主会话裁) 1. `extract_checks.py` **常驻保留**——承担清单维护义务(test-conventions §9.3 锚)的再提取/diff 职能;其 DEFAULT_SRC 悬空问题列入波 2:默认源改为三宿主(game/tests/unit、integration、system_test.gd)遍历,或显式路径参数,波 3 出口对账用显式模式。