T2(D2): 探针只读出口——BoardView/level_map_screen 四出口落地+私有域直入清零(全探针绿+冒烟718/0)
出口四件(形态仿 fx_probe 先例:只读 Dictionary 快照): - BoardView.cells_probe()/diggable_probe()(键面同构快照)+hover_probe()/fog_params_probe() (后两件=D2 清单外同类项随批收口:_hover 1 处+_fog_lantern/_fog_enabled 2 处,完成定义 「私有域直入清零」口径,26 处 > 任务书盘点 ~22 处——超出面系断言消息实参里的隐性直读) - level_map_screen.layout_probe(nodes)/canvas_probe()(origin+min_size 快照) 消费侧改写:ui_input_probe 24 处(含循环体三处快照局部变量防逐迭代 duplicate)、 ui_probe 2 处、ui_click_probe 1 处;grep 复核 _cells/_diggable/_hover/_fog_*/_layout/_canvas 探针侧零残留。组合根接缝面(_row_queue 等)按边界注记不入本卡。烟测断言数 718 持平。
This commit is contained in:
1 parent
cd7d3ea401
commit
22417783db
5 files changed
+72
-31
No files matched your search
@@ -1117,3 +1117,26 @@ func _make_cursor_texture(glyph: String) -> ImageTexture:
|
||||
if f != null:
|
||||
f.draw_string(img, Vector2(2, 18), glyph, HORIZONTAL_ALIGNMENT_LEFT, 20, 18, COL_DIGIT)
|
||||
return ImageTexture.create_from_image(img)
|
||||
|
||||
|
||||
# ---- 探针只读出口(D2 改造 2026-10-04——_cells/_diggable 私有容器直入退役;形态仿 fx_probe 先例:只读快照) ----
|
||||
|
||||
# 格件映射只读快照(Vector2i → CellUnit;键面同构——断言语义零变化;破私有面的只是容器字典,
|
||||
# 格件字段本为公有呈现面,快照值即原格件引用)
|
||||
func cells_probe() -> Dictionary:
|
||||
return _cells.duplicate()
|
||||
|
||||
|
||||
# 可挖域只读快照(Vector2i → true;8 向相邻未开格=呼吸微光作用集)
|
||||
func diggable_probe() -> Dictionary:
|
||||
return _diggable.duplicate()
|
||||
|
||||
|
||||
# 悬停格只读出口(case① 悬停到达断言消费面——_hover 私有域直入退役,D2 清单外同类项随批收口)
|
||||
func hover_probe() -> Vector2i:
|
||||
return _hover
|
||||
|
||||
|
||||
# 迷雾参数只读快照(case⑮ 参数漂移断言消费面——_fog_lantern/_fog_enabled 私有域直入退役,D2 清单外同类项随批收口)
|
||||
func fog_params_probe() -> Dictionary:
|
||||
return {"lantern": _fog_lantern, "enabled": _fog_enabled}
|
||||
@@ -468,6 +468,18 @@ func _layout(nodes: Array, canvas: Control) -> Dictionary:
|
||||
return pos
|
||||
|
||||
|
||||
# ---- 探针只读出口(D2 改造 2026-10-04——_layout/_canvas 私有域直入退役;形态仿 fx_probe 先例:只读快照) ----
|
||||
|
||||
# 选路布局只读快照(node → 局部位置;画布固定取现行 _canvas,调用侧零私有域触达)
|
||||
func layout_probe(nodes: Array) -> Dictionary:
|
||||
return _layout(nodes, _canvas)
|
||||
|
||||
|
||||
# 路由画布只读快照(origin=全局原点;min_size=最小拟合尺寸——画布拟合断言消费面)
|
||||
func canvas_probe() -> Dictionary:
|
||||
return {"origin": _canvas.get_global_position(), "min_size": _canvas.custom_minimum_size}
|
||||
|
||||
|
||||
# 分层(layout/fit 共享件):layer = 入口 BFS 深度;同层 slot 垂直排布;未达节点兜底排末层
|
||||
func _assign_layers(nodes: Array, layer: Dictionary, slot: Dictionary) -> void:
|
||||
var layer_counts := {}
|
||||
|
||||
@@ -177,7 +177,7 @@ func _ready() -> void:
|
||||
var first_cell_ms := t_entry
|
||||
if first_cell_ms > 500:
|
||||
_problems.append("进入战斗屏首格可点超时 %dms > 500ms" % first_cell_ms)
|
||||
if main.board_view._cells.is_empty():
|
||||
if main.board_view.cells_probe().is_empty():
|
||||
_problems.append("首格未可点(cells=0)")
|
||||
print("[click_probe] 首格可点计时 %dms(进入战斗屏口径,≤500ms AC)· 场景冷启动 %dms(含 UI 构建 %dms,观测项)" % [
|
||||
first_cell_ms, t_total, t_ui_ready])
|
||||
|
||||
@@ -45,8 +45,8 @@ func _ready() -> void:
|
||||
for n in nds:
|
||||
if main.runner.node_id_of(n) == int(cands[0]):
|
||||
tgt = n
|
||||
var npos: Vector2 = ro._layout(nds, ro._canvas)[tgt]
|
||||
var gpos: Vector2 = ro._canvas.get_global_position() + npos
|
||||
var npos: Vector2 = ro.layout_probe(nds)[tgt]
|
||||
var gpos: Vector2 = ro.canvas_probe()["origin"] + npos
|
||||
var evm := InputEventMouseMotion.new()
|
||||
evm.position = gpos
|
||||
evm.global_position = gpos
|
||||
@@ -97,12 +97,13 @@ func _ready() -> void:
|
||||
# 常数锚(画布拟合探针):70/122/26/8 与 presentation/views/level_map_screen.gd 的 _content_size
|
||||
# 公式(70 + maxl*122 + NODE_HALF.x + 8)同源复刻——改常数须两侧同步(本探针只读断言层,真源在屏)
|
||||
var need_x2: float = 70.0 + maxl2 * 122.0 + 26.0 + 8.0
|
||||
if float(ro2._canvas.custom_minimum_size.x) < need_x2 - 0.5:
|
||||
_pre_fail("画布拟合不足(min.x=%.0f < 最深内容 %.0f——深层节点不可点回归)" % [ro2._canvas.custom_minimum_size.x, need_x2])
|
||||
var cvmin: Dictionary = ro2.canvas_probe()
|
||||
if float(cvmin["min_size"].x) < need_x2 - 0.5:
|
||||
_pre_fail("画布拟合不足(min.x=%.0f < 最深内容 %.0f——深层节点不可点回归)" % [cvmin["min_size"].x, need_x2])
|
||||
var bv = main.board_view
|
||||
var ms = main.settlement.minesweeper if main.settlement != null else null
|
||||
if ms == null or bv._cells.is_empty():
|
||||
_pre_fail("战斗未就绪(cells=%d settlement=%s)" % [bv._cells.size(), str(main.settlement)])
|
||||
if ms == null or bv.cells_probe().is_empty():
|
||||
_pre_fail("战斗未就绪(cells=%d settlement=%s)" % [bv.cells_probe().size(), str(main.settlement)])
|
||||
return
|
||||
bv.action_requested.connect(func(c: Vector2i, kind: String): _actions.append([c, kind]))
|
||||
bv.chord_attempted.connect(func(c: Vector2i): _chords.append(c))
|
||||
@@ -130,7 +131,7 @@ func _ready() -> void:
|
||||
# 并流批(ADR-0007 裁丙 2026-09-27)后首战板面种子随全局序漂移——_diggable(主角 8 邻未开域)
|
||||
# 不足两枚时,沿已开区真点击移位到「≥2 未开邻」的前沿格再选;移位失败即收手交由选取失败分支报状态
|
||||
for _expand in range(16):
|
||||
if bv._diggable.size() >= 2:
|
||||
if bv.diggable_probe().size() >= 2:
|
||||
break
|
||||
var mv_t := Vector2i(-9, -9)
|
||||
for y in bv._board.height:
|
||||
@@ -157,7 +158,7 @@ func _ready() -> void:
|
||||
break
|
||||
var flag_t := Vector2i(-9, -9)
|
||||
var dig_t := Vector2i(-9, -9)
|
||||
for c in bv._diggable:
|
||||
for c in bv.diggable_probe():
|
||||
if not ms.has_flag(c):
|
||||
if flag_t.x == -9:
|
||||
flag_t = c
|
||||
@@ -172,9 +173,9 @@ func _ready() -> void:
|
||||
# ---- case① 悬停可挖域:motion → 悬停态到达(金框 + 十字光标)----
|
||||
_push_motion(_pos(bv, flag_t))
|
||||
await get_tree().process_frame
|
||||
if bv._hover != flag_t:
|
||||
_problems.append("case① 悬停未到达(_hover=%s 应=%s)" % [bv._hover, flag_t])
|
||||
var u1 = bv._cells[flag_t]
|
||||
if bv.hover_probe() != flag_t:
|
||||
_problems.append("case① 悬停未到达(_hover=%s 应=%s)" % [bv.hover_probe(), flag_t])
|
||||
var u1 = bv.cells_probe()[flag_t]
|
||||
if not u1.hl_visible or u1.hl_color != UiKit.GOLD:
|
||||
_problems.append("case① 悬停金框缺失(visible=%s color=%s)" % [str(u1.hl_visible), str(u1.hl_color)])
|
||||
if bv.mouse_default_cursor_shape != Input.CURSOR_CROSS:
|
||||
@@ -184,14 +185,14 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if _forbids.is_empty() or _forbids[_forbids.size() - 1] != forbid_t:
|
||||
_problems.append("case② hover_forbidden 未达(%s)" % [str(_forbids)])
|
||||
if bv._cells[forbid_t].hl_color != UiKit.RED_FORBID:
|
||||
_problems.append("case② 禁入红框缺失(color=%s)" % str(bv._cells[forbid_t].hl_color))
|
||||
if bv.cells_probe()[forbid_t].hl_color != UiKit.RED_FORBID:
|
||||
_problems.append("case② 禁入红框缺失(color=%s)" % str(bv.cells_probe()[forbid_t].hl_color))
|
||||
# ---- case③ 悬停已开格:路径预览点迹 + 移动光标 ----
|
||||
_push_motion(_pos(bv, reveal_t))
|
||||
await get_tree().process_frame
|
||||
var dots := 0
|
||||
for c in bv._cells:
|
||||
if bv._cells[c].dot_visible:
|
||||
for c in bv.cells_probe():
|
||||
if bv.cells_probe()[c].dot_visible:
|
||||
dots += 1
|
||||
if dots < 1:
|
||||
_problems.append("case③ 路径预览点迹未亮(dots=0)")
|
||||
@@ -208,7 +209,7 @@ func _ready() -> void:
|
||||
# ---- case④b 旗纹理槽回归断言(P0-1 修复批 2026-10-02):T13 批曾在 paint 尾部无条件
|
||||
# `u.tex_flag = null` 覆盖 T17 批的条件赋值=素材在位时插旗不可见(headless 缺盘走字形回退
|
||||
# 掩盖)——有盘断言纹理在槽、缺盘断言字形回退,两分支防双写踩踏复活 ----
|
||||
var flag_unit = bv._cells.get(flag_t)
|
||||
var flag_unit = bv.cells_probe().get(flag_t)
|
||||
if bv._flag_tex != null:
|
||||
if flag_unit == null or flag_unit.tex_flag != bv._flag_tex:
|
||||
_problems.append("case④b 旗纹理槽未挂封印旗纹理(tex_flag=%s)" % ["无单元" if flag_unit == null else str(flag_unit.tex_flag)])
|
||||
@@ -298,7 +299,7 @@ func _ready() -> void:
|
||||
# 必须回退「人」(数字格仍显数字——回退判据与抑制判据同源);验毕还原纹理重绘。 ----
|
||||
if bv._world.hero != null:
|
||||
var hp11: Vector2i = ms.hero_pos()
|
||||
var u11 = bv._cells[hp11]
|
||||
var u11 = bv.cells_probe()[hp11]
|
||||
var tex_saved: Texture2D = bv._hero_tex_idle
|
||||
bv._hero_tex_idle = null
|
||||
bv.refresh()
|
||||
@@ -315,23 +316,25 @@ func _ready() -> void:
|
||||
if mark_t.x >= 0:
|
||||
bv.set_variant_mark_resolver(func(_c): return "flat_damage")
|
||||
bv.refresh()
|
||||
if String(bv._cells[mark_t].mutation_mark) != "flat_damage":
|
||||
_problems.append("case⑭ 变异角标未落位(mutation_mark=%s)" % str(bv._cells[mark_t].mutation_mark))
|
||||
if String(bv.cells_probe()[mark_t].mutation_mark) != "flat_damage":
|
||||
_problems.append("case⑭ 变异角标未落位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].mutation_mark))
|
||||
bv.set_variant_mark_resolver(Callable())
|
||||
bv.refresh()
|
||||
if String(bv._cells[mark_t].mutation_mark) != "":
|
||||
_problems.append("case⑭ 角标未随 resolver 复位(mutation_mark=%s)" % str(bv._cells[mark_t].mutation_mark))
|
||||
if String(bv.cells_probe()[mark_t].mutation_mark) != "":
|
||||
_problems.append("case⑭ 角标未随 resolver 复位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].mutation_mark))
|
||||
else:
|
||||
_problems.append("case⑭ 无未开格可验(板面异常)")
|
||||
# ---- case⑮ 视野迷雾(迭代 11 第④批 T5——三态呈态/半径圈/移动跟随/开关两态零扰动/提灯插值位;
|
||||
# 纯呈现零逻辑——迷雾开关切换前后 minesweeper 状态摘要逐位一致) ----
|
||||
if int(bv.FOG_RADIUS) != 8 or int(bv.FOG_LANTERN_BONUS) != 2 or int(bv._fog_lantern) != 0 or not bv._fog_enabled:
|
||||
var fogp: Dictionary = bv.fog_params_probe()
|
||||
if int(bv.FOG_RADIUS) != 8 or int(bv.FOG_LANTERN_BONUS) != 2 or int(fogp["lantern"]) != 0 or not fogp["enabled"]:
|
||||
_problems.append("case⑮ 迷雾参数漂移(R=%s bonus=%s lantern=%s enabled=%s 应=8/2/0/true)"
|
||||
% [str(bv.FOG_RADIUS), str(bv.FOG_LANTERN_BONUS), str(bv._fog_lantern), str(bv._fog_enabled)])
|
||||
% [str(bv.FOG_RADIUS), str(bv.FOG_LANTERN_BONUS), str(fogp["lantern"]), str(fogp["enabled"])])
|
||||
else:
|
||||
var hero15: Vector2i = ms.hero_pos()
|
||||
var b15 = ms.current_board()
|
||||
var fog_ok := true
|
||||
var cells_f1: Dictionary = bv.cells_probe()
|
||||
for y in b15.height:
|
||||
for x in b15.width:
|
||||
var c15 := Vector2i(x, y)
|
||||
@@ -339,7 +342,7 @@ func _ready() -> void:
|
||||
var expect15: int = 0
|
||||
if d15 > bv.FOG_RADIUS:
|
||||
expect15 = 2 if ms.is_revealed(c15) else 1
|
||||
var got15: int = int(bv._cells[c15].fog_state)
|
||||
var got15: int = int(cells_f1[c15].fog_state)
|
||||
if got15 != expect15:
|
||||
fog_ok = false
|
||||
_problems.append("case⑮ 迷雾呈态不符(%s dist=%d got=%d expect=%d)" % [str(c15), d15, got15, expect15])
|
||||
@@ -348,11 +351,12 @@ func _ready() -> void:
|
||||
break
|
||||
# 半径边界格恰在圈内(曼哈顿距离恰 =R 的格 fog_state=0——存在性校验,12×12 板必有)
|
||||
var has_boundary := false
|
||||
var cells_f2: Dictionary = bv.cells_probe()
|
||||
for y in b15.height:
|
||||
for x in b15.width:
|
||||
if absi(x - hero15.x) + absi(y - hero15.y) == int(bv.FOG_RADIUS):
|
||||
has_boundary = true
|
||||
if int(bv._cells[Vector2i(x, y)].fog_state) != 0:
|
||||
if int(cells_f2[Vector2i(x, y)].fog_state) != 0:
|
||||
_problems.append("case⑮ 边界圈内格被误遮(dist==R 应 fog_state=0)")
|
||||
break
|
||||
if has_boundary:
|
||||
@@ -369,9 +373,10 @@ func _ready() -> void:
|
||||
digest_before.append(ms.is_revealed(c16))
|
||||
bv.set_fog_enabled(false)
|
||||
var all_clear := true
|
||||
var cells_f3: Dictionary = bv.cells_probe()
|
||||
for y in b15.height:
|
||||
for x in b15.width:
|
||||
if int(bv._cells[Vector2i(x, y)].fog_state) != 0:
|
||||
if int(cells_f3[Vector2i(x, y)].fog_state) != 0:
|
||||
all_clear = false
|
||||
if not all_clear:
|
||||
_problems.append("case⑮ 迷雾关未全板归零(off 态应 fog_state=0)")
|
||||
@@ -383,7 +388,7 @@ func _ready() -> void:
|
||||
if digest_off != digest_before:
|
||||
_problems.append("case⑮ 迷雾开关改写逻辑态(两态结算逐位一致 🔴 契约破)")
|
||||
bv.set_fog_enabled(true)
|
||||
if int(bv._cells[Vector2i(0, 0)].fog_state) == 0 \
|
||||
if int(bv.cells_probe()[Vector2i(0, 0)].fog_state) == 0 \
|
||||
and absi(0 - hero15.x) + absi(0 - hero15.y) > int(bv.FOG_RADIUS):
|
||||
_problems.append("case⑮ 迷雾复开后远角未复原遮蔽(fog_state=0)")
|
||||
if _problems.is_empty():
|
||||
@@ -405,10 +410,11 @@ func _has_action(cell: Vector2i, kind: String) -> bool:
|
||||
|
||||
func _pick_forbidden(bv, ms) -> Vector2i:
|
||||
var b = ms.current_board()
|
||||
var digp: Dictionary = bv.diggable_probe()
|
||||
for y in b.height:
|
||||
for x in b.width:
|
||||
var c := Vector2i(x, y)
|
||||
if not ms.is_revealed(c) and not bv._diggable.has(c):
|
||||
if not ms.is_revealed(c) and not digp.has(c):
|
||||
return c
|
||||
return Vector2i(-9, -9)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ func _ready() -> void:
|
||||
if main.adventure == null or String(main.adventure.state) != "running":
|
||||
problems.append("首战中放弃未被拒(战斗域单事务在飞——state 应保持 running)")
|
||||
# ---- 既有断言(回归基线;A 区进度条断言随 停点前移批 2026-09-23 退役——节点链进度由关卡画面独立屏承载)----
|
||||
if main.board_view._cells.is_empty():
|
||||
if main.board_view.cells_probe().is_empty():
|
||||
problems.append("棋盘格未生成(cells=0)")
|
||||
if main.board_view.board() == null:
|
||||
problems.append("board 未装载")
|
||||
@@ -228,7 +228,7 @@ func _ready() -> void:
|
||||
main._close_modal(main._end_overlay)
|
||||
if problems.is_empty():
|
||||
print("[ui_probe] PASS — cells=%d board=%dx%d hp='%s' enemies=%d ap_dots=%d" % [
|
||||
main.board_view._cells.size(), main.board_view.board().width, main.board_view.board().height,
|
||||
main.board_view.cells_probe().size(), main.board_view.board().width, main.board_view.board().height,
|
||||
main.info_panel.attack_text(),
|
||||
main.stage.enemy_box.get_child_count(), main.ap_bar._dots.get_child_count()])
|
||||
get_tree().quit(0)
|
||||
|
||||
Reference in new issue
Block a user