# VERTICAL SLICE - NOT FOR PRODUCTION # Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2) # Date: 2026-09-10 # 棋盘产物数据契约(排雷玩法消费;生成后不可变——排雷玩法持快照即持活引用,生成器不再触碰)。 # 实现 GDD:design/archive/gdd-2026-09-14/a1-board-generation.md(系统 ID A1·棋盘生成——registry 追溯锚,命名规范见 CLAUDE.md) class_name BoardData extends RefCounted var width: int = 0 var height: int = 0 var spawn_center := Vector2i.ZERO var mines := {} # Vector2i → true var digits := {} # Vector2i → int(安全格恒有值;数字恒真 = 8 邻雷数) var variants := {} # Vector2i → Array[String](生成期快照,抗表重载) var board_type := "" # 图类型标签(词表 v1.0:dungeon/underdark;玩家侧显示名「地图类型」) var level_index: int = 1 var node_depth: int = 0 var metrics := {} # 生成期指标集(键清单单点定义在 board_generator._finalize) var illegal_product := false # 非法产物标记(接受最不坏出口——零合法板诚实降级) var degraded_product := false # 降级产物标记(接受最优出口——有合法板但无一达标;与 illegal_product 对称) func in_bounds(c: Vector2i) -> bool: return c.x >= 0 and c.y >= 0 and c.x < width and c.y < height func index_of(c: Vector2i) -> int: return c.y * width + c.x func is_mine(c: Vector2i) -> bool: return mines.has(c) func is_safe(c: Vector2i) -> bool: return in_bounds(c) and not mines.has(c) func digit_of(c: Vector2i) -> int: return digits.get(c, -1) func variant_ids(c: Vector2i) -> Array: return variants.get(c, []) func has_variant(c: Vector2i, vid: String) -> bool: return variant_ids(c).has(vid) func neighbors8(c: Vector2i) -> Array: var out: Array[Vector2i] = [] for dy in range(-1, 2): for dx in range(-1, 2): if dx == 0 and dy == 0: continue var n := Vector2i(c.x + dx, c.y + dy) if in_bounds(n): out.append(n) return out # 行主序(规范序的邻接枚举基序) func spawn_cells() -> Array: var out: Array[Vector2i] = [] for dy in range(-1, 2): for dx in range(-1, 2): var c := Vector2i(spawn_center.x + dx, spawn_center.y + dy) if in_bounds(c): out.append(c) return out func all_cells() -> Array: var out: Array[Vector2i] = [] for y in height: for x in width: out.append(Vector2i(x, y)) return out func safe_cells() -> Array: var out: Array[Vector2i] = [] for c in all_cells(): if is_safe(c): out.append(c) return out # R₀ = 出生 3×3 ∪ (出生 3×3 经 0 格的 flood 闭包)——与 排雷玩法 F3 逐字同构(棋盘生成 F1 求解器初始态)。 func compute_r0() -> Array: var b3 := spawn_cells() var r0 := {} for c in b3: r0[c] = true var queue: Array = b3.duplicate() while not queue.is_empty(): var c: Vector2i = queue.pop_front() if is_safe(c) and digit_of(c) == 0: # 变异死分支退役(2026-09-18 用户拍板删——与 排雷玩法 展开实现口径归一;变异定稿批按正式语义重接) for n in neighbors8(c): if is_safe(n) and not r0.has(n): r0[n] = true queue.append(n) return r0.keys()