Files
gplan-2/game/core/board_data.gd
T
DKChan 32fdf957fd refactor(代码术语): 卡① flag→seal 全族换代+game/ 禁用词清扫(迭代 31 卡①)
标识符面:flag_*→seal_ 族(含 Godot 信号 flag_judged→seal_judged 与连接/回调同名、
FACTS 两键 flags_count→seals_count/dug_under_flag→dug_under_seal 全链、
.tres 键名与 schema .gd 同批同步);显式豁免零改动=size_flags_*(Godot 布局属性)+_fatal_flag。
中文面:金币→GP(金币袋→GP 袋)/插旗→封印/雷格→危险格/惩罚格→危险格/旗→封印·封印印记族,
game/ 内 *.gd/.tres/.md/.json 四类禁用词与 flag 双双零命中(V1/V4)。
守卫字面量不动(被检查的禁字不是使用):smoke_all V21 零「雷/旗」检查面、
ui_font_asset_test 字形集攻/雷/旗/封 保持原断言逻辑。
代拍板:板面单字槽 glyph「旗」→「封」(禁字纪律+单字位宽,消费面四处同名随动)。
素材换代(2026-10-18 用户裁案甲):assets/art/board/flag_seal.png→seal_mark.png(素材不入 git,
盘上改名+导入重刷),代码两处 res:// 字符串+COL_FLAG/CURSOR_FLAG 常量同步,
闸件四处随批(run_all_gates.sh/render_gate.sh/golden_baseline_refresh.sh/path_check.py)。
anchor.json 键名手改,重锚与改前改后 diff 随本卡收口(同裁案甲)。

基线读数(改前,主区 ed2dfaf6):冒烟 1151 检查 0 失败/单元 34 套全绿/探针 --click
存量红仅 screen_flow_probe(user:// 断点污染在册已知项)。
改后同批读数(本 worktree):冒烟 1151 检查 0 失败/探针 --click 同一存量红、其余全绿。
2026-10-19 02:52:38 +08:00

112 lines
4.1 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## VERTICAL SLICE - NOT FOR PRODUCTION
## 棋盘产物数据契约:生成器产出、排雷玩法消费的格子事实集(垂直切片验证:战斗内棋盘事实逐行归因)。
## 生成后不可变——消费方持引用只读,禁原地改写;跨类「棋盘事实不可变」约定由本不可变性承载。
class_name BoardData
extends RefCounted
# 出生 3×3 区格数(2026-10-02 修复批 T2 魔法数结构化——W×H−9 布雷域基的双落点收口单点:
# 棋盘生成 _attempt/_finalize 与 BoardGenTable 布雷数下限校验共用;与 spawn_cells() 的 3×3 几何同源)
const SPAWN_AREA_CELLS := 9
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_variants: Array[String] = [] # 板级变异 id 集(scope=global 整图作用域——全局作用域变异批 2026-10-04:
# 战斗编排装板决议写入,随图生灭同 variants;普通图恒空)
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
# 行主序排序键(2026-10-02 修复批——排雷玩法 封印判定批与 地图战斗资源 资格规范化两处手抄收口单点):
# y×1000+x 字典序 = 行主序;板宽域 [8,64] 远小于 1000,x 不跨行、键值不碰撞。
static func row_major_key(c: Vector2i) -> int:
return c.y * 1000 + 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, [])
# 板级变异只读出口(scope=global 行集——呈现快照/断言消费;空 = 无全局型合法态)
func board_variant_ids() -> Array[String]:
return board_variants
# 中和格变异(迭代 12 T6 净化工兵——伤害型地形格变普通格;🔴 R4 甲仅限伤害型的过滤在调用方)
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[Variant] = 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()