# VERTICAL SLICE - NOT FOR PRODUCTION # Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2) # Date: 2026-09-10 # 一次性检查脚本:打印一场完整战斗的结算步骤流 + 棋盘摘要(肉眼验收 P2 归因质量)。 # 运行:Godot_console.exe --headless --path . --script res://smoke/dump_battle.gd extends SceneTree const BattleDriver := preload("res://smoke/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现) func _initialize() -> void: var db = load("res://core/config_db.gd").new() db.load_tables("res://data/tables", false) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(42) # 种子 = 42;第二个命令行参数可覆盖(关卡 种子) var settlement = load("res://core/battle_orchestrator.gd").new(db, rng) var stream: Array = [] settlement.step_row.connect(func(row): stream.append(row)) var level := 2 if OS.get_cmdline_user_args().size() > 0: level = int(OS.get_cmdline_user_args()[0]) if OS.get_cmdline_user_args().size() > 1: rng.set_master_seed(int(OS.get_cmdline_user_args()[1])) settlement.begin_battle({"level_index": level, "node_depth": 0, "hero_hp": db.hero.max_hp}) print("=== 棋盘摘要 L%d ===" % level) var bd = settlement.minesweeper.current_board() print("尺寸 %dx%d · 雷 %d · 安全格 %d · R₀ %d" % [bd.width, bd.height, bd.mines.size(), bd.safe_cells().size(), bd.metrics.r0_count]) print("指标: inferability=%.3f attempts=%s accept=%s" % [bd.metrics.inferability, bd.metrics.attempts_used, bd.metrics.accept_mode]) var rounds := 0 while settlement.battle_result == "" and rounds < 40: rounds += 1 BattleDriver.drive_round(settlement) # T6 收口:原内联循环语义同型(移动期免 AP——移动不换轮,移位后重查 break 分支为防御性等价) print("战斗结果: %s(%d 轮)" % [settlement.battle_result, rounds]) print("=== 结算步骤流(%d 行)===" % stream.size()) for row in stream: print(JSON.stringify(row)) quit(0)