iter50-卡3:卡C(架构审查3.1+3.2整改): T0基线对账+乙案规则键参数字典全库贯通+丙案节点图三参数入表域并单点+戊案出生区入表+丁案经济三件+甲案死效果通道退役+A类①双写四处置+庚案驱动循环收敛+己案sim信息面出口(preview_reveal+0格连锁)+组D退役+组C确认; 断言V1-V15+负面件+新件4; 77套件+gdstyle 0新增全绿; 产出物实现报告与反哺点清单落位

This commit is contained in:
DKChan committed 2026-11-03 06:31:05 +08:00
1 parent cd133932f9
commit a2886a5336
361 files changed
+7291 -736

No files matched your search

+8 -38
View File
@@ -9,7 +9,6 @@ extends RefCounted
const NODE_TYPES := ["battle", "boss", "reward", "rest", "shop"]
const FILLER_TYPES := ["battle", "reward", "rest"]
const MAX_WIDTH := 4 # 产出约束·宽度=分叉生长(同深度节点数由岔口长出 1→2→3→4,禁摆平行层)
# 多终点图的支路互斥段必须各有独有类型(契约 5③),而商店与 Boss 是每条支路共有件,
# 独有类型只能来自 battle/reward/rest 三件 ⇒ 归属大岔口各区域的填充节点取互斥签名类型。
# 入口与主链段(大岔口上游,不属任何支路互斥段)恒为战斗节点——承载战斗保底与岔口下一跳互异基准形。
@@ -66,40 +65,11 @@ func _setup_and_build(params: Dictionary, seed_val: int) -> Dictionary:
## 参数档可行性判定(执行边界③:参数无解=配置错误)——域校验外加深度预算与战斗保底可放性。
static func check_params(params: Dictionary) -> Array:
var errs: Array[Dictionary] = _cp_domain(params)
if not errs.is_empty():
return errs
# 域校验并单点(R7——参数档域合法性唯一在 LevelGenParams.validate 加载期;
# 生成器只留可行性判定 _cp_structural——schema 无此判定的生成器职责)
return _cp_structural(params)
## 域校验段:五旋钮值域/岔口去路数锁值/配比四类合计 1
static func _cp_domain(params: Dictionary) -> Array[Dictionary]:
var errs: Array[Dictionary] = []
var L := int(params.get("layers", 0))
var e := int(params.get("exit_count", 0))
var en := int(params.get("entry_count", 0))
var bf := int(params.get("battle_floor", -1))
var bd := float(params.get("branch_density", -1.0))
if L < 6:
errs.append({"category": "domain", "message": "层深 %d 低于下限 6(层高已锁)" % L})
if e < 1 or e > 3:
errs.append({"category": "domain", "message": "出口个数 %d 越域 [1,3]" % e})
if en < 1:
errs.append({"category": "domain", "message": "入口个数 %d 越域(≥1)" % en})
if bd < 0.0 or bd > 1.0:
errs.append({"category": "domain", "message": "分支密度 %f 越域 [0,1]" % bd})
if bf < 0:
errs.append({"category": "domain", "message": "战斗保底 %d 越域(≥0)" % bf})
if int(params.get("fork_ways_min", 2)) < 2 or int(params.get("fork_ways_max", 3)) > 3:
errs.append({"category": "domain", "message": "岔口去路数域越界(锁 2/3)"})
var sum := 0.0
for rk in ["battle_ratio", "reward_ratio", "rest_ratio", "shop_ratio"]:
sum += float(params.get(rk, -1.0))
if not is_equal_approx(sum, 1.0):
errs.append({"category": "domain", "message": "配比四类合计 %f ≠ 1" % sum})
return errs
## 结构可行性段:主链段容量与战斗保底可放性(多出口按区域签名累加可放槽)
static func _cp_structural(params: Dictionary) -> Array[Dictionary]:
var errs: Array[Dictionary] = []
@@ -271,8 +241,8 @@ func _vo_width_rules(nodes: Array, errs: Array) -> void:
var d2: int = int(n["depth"])
per_depth[d2] = int(per_depth.get(d2, 0)) + 1
for d3 in per_depth:
if int(per_depth[d3]) > MAX_WIDTH:
errs.append({"category": "structural", "message": "深度 %d 节点数 %d 超分叉生长上限 4(平行层摆放)" % [d3, per_depth[d3]]})
if int(per_depth[d3]) > int(_params["width_max"]):
errs.append({"category": "structural", "message": "深度 %d 节点数 %d 超分叉生长上限(width_max 表值——平行层摆放)" % [d3, per_depth[d3]]})
## 计数规则③·参数档对照:战斗保底/入口数/终点数/层高(params 为空时跳过)
@@ -358,7 +328,7 @@ func _build_region(r: int, e: int, L: int, prevs: Array, terminals: Array) -> vo
## 侧支节点与主去路同深(保持「深度=自入口最长路径步数」不变量),两支各自汇入主去路的后继,
## 于是支路互斥段={主去路节点} 与 {侧支节点}——两支类型互异即同时满足「下一跳互异」与「各有独有类型」。
func _add_forks(rg: RandomNumberGenerator, L: int, t: int, e: int) -> void:
var wanted := clampi(int(round(float(_params["branch_density"]) * float(L))), 1, 24)
var wanted := maxi(int(round(float(_params["branch_density"]) * float(L))), 1) # 死上限 24 删(不可达值——下限 1 保留防零岔口)
var anchors := _collect_fork_anchors(L, t, e)
anchors = _shuffle(rg, anchors)
var selected := {} # 已扩岔节点 id
@@ -377,10 +347,10 @@ func _add_forks(rg: RandomNumberGenerator, L: int, t: int, e: int) -> void:
continue
if (v["next"] as Array).is_empty():
continue # 主去路无后继(无可汇入点)——该锚点弃用
var extra := 2 if (int(_params["fork_ways_max"]) >= 3 and rg.randf() < 0.35) else 1
var extra := 2 if (int(_params["fork_ways_max"]) >= 3 and rg.randf() < float(_params["fork_third_way_pct"]) / 100.0) else 1
var made := 0
for k in range(extra):
if _depth_count(int(v["depth"])) >= MAX_WIDTH:
if _depth_count(int(v["depth"])) >= int(_params["width_max"]):
break
var wid := _mk("battle", int(v["depth"]))
(a["next"] as Array).append(wid)
@@ -452,7 +422,7 @@ func _fill_ratios(rg: RandomNumberGenerator) -> void:
free = _shuffle(rg, free)
var want := int(round(float(_pool.size()) * (float(_params["reward_ratio"]) + float(_params["rest_ratio"]))))
var floor_n := int(_params["battle_floor"])
var rest_first := rg.randf() < 0.5
var rest_first := rg.randf() < float(_params["fill_rest_first_pct"]) / 100.0
for i in range(want):
if i >= free.size():
break