test(迁移): 批 B 波 1 G4 套1 敌方攻击类型轴四条迁入 roll_multiplier_test.gd——新宿主落位+manifest 登记+剪切挂载绿+按条变异 4/4 验红(表列越轨/快照清空连带载荷矩阵/载荷置空/矩阵查表短路各验红);smoke_all.gd 同批删函数节头与调用行;闸01 剩余面 1015 绿
This commit is contained in:
1 parent
5f190bc354
commit
fdb77ffeea
4 files changed
+101
-62
No files matched your search
@@ -0,0 +1,93 @@
|
||||
# tests/unit/battle_settlement/roll_multiplier_test.gd — 掷点与乘区单元测试宿主
|
||||
# 断言面 = 五套(批 B 断言迁移自 smoke_all.gd,G4 施工组;五套按源编排序分五笔原子提交迁入):
|
||||
# 敌方攻击类型轴(表列全 normal / spawn 快照注入 / 单据载荷第 9 参 / 克制矩阵命中证词 ±1 位移)
|
||||
# 护甲等级掷点·行为面(查档纯函数分布 / EV 锚 / nat20 暴击 / 削弱续时 / AC11 逐拍判定 / 伤害下限 / 棋盘来源必中)
|
||||
# 主角乘区接线 + 硬化折半方向(×1.5 / ×0.75 / ×0.5——池乘区通道)
|
||||
# 攻击类型 × 护甲克制 + 标错惩罚(护甲快照 / 克制矩阵表值 / 标错负向与标中正向兑付 / 同种子回放)
|
||||
# 战斗结算 fresh 池攻击链回归(Bug#2——池空时按掷点档位足额兑现)
|
||||
# 协议照单元侧惯例:extends SceneTree+Kit.check 主通道;--script 模式无 autoload,
|
||||
# ConfigDB 显式实例化构造注入(各套自建 RngService——源套掷点隔离形态,宿主不持统一流);
|
||||
# 表加载失败不中止(沿被迁断言面的源语义——诊断在此展开,表值变异的红由具体断言落,承 G2/G3 同款)。
|
||||
# 运行:godot --headless --path game --script res://tests/unit/battle_settlement/roll_multiplier_test.gd
|
||||
extends SceneTree
|
||||
|
||||
const Kit := preload("res://tests/unit/test_kit.gd")
|
||||
const ConfigDBScript := preload("res://core/config_db.gd")
|
||||
|
||||
var _db
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_db = ConfigDBScript.new()
|
||||
# 表加载失败不中止(承 G2/G3 同款:表损坏的红落在具体断言上——
|
||||
# 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评)
|
||||
var load_ok: bool = _db.load_tables("res://data/tables", true)
|
||||
if not load_ok:
|
||||
push_error("[roll_multiplier_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])
|
||||
# 套执行序沿源编排序
|
||||
_smoke_enemy_attack_type()
|
||||
quit(Kit.finish("roll_multiplier_test"))
|
||||
|
||||
|
||||
# ---- 敌方攻击类型轴(表列/单位快照/单据载荷/矩阵命中证词)----
|
||||
# 克制矩阵命中证词 = 同种子三甲型配对实测(不是查表存在性证词):同种子下 armor_roll 流消费逐位一致、
|
||||
# 阈值(hero armor_class)不变,三甲型唯一差异 = 克制点数 cdelta(normal_vs_light 0 / heavy −1 / ward +1)
|
||||
# → heavy 伤害 == light −1、ward == light +1(要求基线伤害 ≥ 2——地板 1 会吞 −1 位移)。
|
||||
# 承伤位移红线(卡片 §8 L3):全局位移只允许 ±1 量级——非此量级 = 矩阵消费面有未盘点的第二落点(停机)。
|
||||
func _smoke_enemy_attack_type() -> void:
|
||||
print("--- 敌方攻击类型轴(迭代 24 N3)---")
|
||||
# ① 表列:20 行全填 normal(N3 全填不做差异化——Q9)
|
||||
var at_ok := true
|
||||
var at_detail := ""
|
||||
for row in _db.enemy.rows:
|
||||
var at := String(row.get("attack_type", ""))
|
||||
if at != "normal":
|
||||
at_ok = false
|
||||
at_detail += " %s:%s" % [String(row.get("enemy_id", "?")), at]
|
||||
Kit.check("敌方 %d 行 attack_type 全填 normal(迭代 24 N3 轴开列,越轨行%s)" % [
|
||||
_db.enemy.rows.size(), at_detail if at_detail != "" else "无"], at_ok)
|
||||
# ②③④ 矩阵命中证词扫描:(3,0) 灰矮人 atk 区间 [2,4] 基线足够((1,2) 熊地精 atk 1 会塌地板);
|
||||
# 同 seed 三甲型各开一场、各取首个敌方伤害行,对拍 ±1。
|
||||
var matrix_found := false
|
||||
var snap_ok := true
|
||||
var payload_at := ""
|
||||
var t_light := -1
|
||||
var t_heavy := -1
|
||||
var t_ward := -1
|
||||
for seed_offset in range(40):
|
||||
var totals := {}
|
||||
for armor in ["light", "heavy", "ward"]:
|
||||
var rng = load("res://core/rng_service.gd").new()
|
||||
rng.set_master_seed(20261013 + seed_offset)
|
||||
var settlement = load("res://core/battle_orchestrator.gd").new(_db, rng)
|
||||
var rows: Array = []
|
||||
settlement.step_row.connect(func(row): rows.append(row))
|
||||
if not settlement.begin_battle({"level_index": 3, "node_depth": 0, "hero_hp": int(_db.hero.max_hp), "armor_type": armor}):
|
||||
totals[armor] = -1
|
||||
continue
|
||||
if armor == "light":
|
||||
for u in settlement._enemy_system.all_enemies():
|
||||
if String(u.get("attack_type", "")) == "":
|
||||
snap_ok = false
|
||||
settlement.minesweeper.settle_batch([{"action": "stop"}])
|
||||
for row in rows:
|
||||
if String(row.get("type", "")) == "damage" and String(row.get("source_class", "")) == "enemy_action":
|
||||
totals[armor] = int(row.get("value", 0))
|
||||
if armor == "light":
|
||||
payload_at = String(row.get("attack_type", "")) # 载荷摊平在行顶层(_emit_row 摊平 extra)
|
||||
break
|
||||
if not totals.has(armor):
|
||||
totals[armor] = -1
|
||||
if int(totals.get("light", -1)) >= 2 and int(totals.get("heavy", -1)) >= 1 and int(totals.get("ward", -1)) >= 1:
|
||||
t_light = int(totals["light"])
|
||||
t_heavy = int(totals["heavy"])
|
||||
t_ward = int(totals["ward"])
|
||||
matrix_found = (t_heavy == t_light - 1 and t_ward == t_light + 1)
|
||||
break
|
||||
Kit.check("敌方单位快照 attack_type 非空(spawn 注入面——迭代 24 N3)", snap_ok)
|
||||
Kit.check("克制矩阵命中证词:同种子三甲型实测 heavy %d == light %d − 1 · ward %d == light %d + 1(迭代 24 N3 全局平移 −1/0/+1)" % [
|
||||
t_heavy, t_light, t_ward, t_light], matrix_found and t_light >= 2)
|
||||
Kit.check("敌方伤害技单据载荷 attack_type 非空(= %s——第 9 参传值面,迭代 24 N3)" % payload_at, payload_at == "normal")
|
||||
Reference in new issue
Block a user