Files
gplan-2/game/core/board_data.gd
T

104 lines
3.3 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
# 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()