From c82ef23f5119240e696c32b79c84a62e8509f6a3 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Fri, 30 Oct 2026 05:58:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=A1=E2=91=A2T1(=E6=B5=8B=E9=80=9F?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF=E6=89=B9v1.1):=20=E6=AD=A5=E8=BF=9B=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9C=BA=E6=94=B9=E9=80=A0=E2=80=94=E2=80=94run(n)?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF=E5=86=85await=E6=94=B9process=5Fframe?= =?UTF-8?q?=E4=BF=A1=E5=8F=B7=E5=B8=B8=E9=A9=BB=E8=BF=9E=E6=8E=A5+=5Fstep?= =?UTF-8?q?=5Fframe=E9=80=90=E5=B8=A7=E5=9B=9E=E8=B0=83(=E6=AF=8F=E5=B1=80?= =?UTF-8?q?=E6=81=B0=E5=8D=A0=E4=B8=80=E5=B8=A7=C2=B7=E9=A6=96=E6=AD=A5?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=C2=B7=E6=AC=A1=E5=B8=A7=E6=96=AD=E8=BF=9E?= =?UTF-8?q?=E6=94=B6=E5=B0=BE=E6=94=BE=E8=A1=8C)+=E6=94=B6=E5=B0=BE?= =?UTF-8?q?=E5=9B=9B=E8=AF=AD=E5=8F=A5=E5=90=8C=E5=B8=A7=E5=90=8C=E7=9B=B8?= =?UTF-8?q?=E4=BD=8D=E8=BF=81=E5=85=A5=5Ffinish=5Fbatch(=E6=AC=A1=E5=BA=8F?= =?UTF-8?q?=E5=AF=B9=E9=BD=90run=E5=B0=BE=E7=8E=B0=E8=A1=8C=E5=BD=A2?= =?UTF-8?q?=E6=80=81)+=5Frun=5Fone=5Flevel=E9=9B=B6=E8=A7=A6=E7=A2=B0;?= =?UTF-8?q?=E5=85=A8=E6=96=87=E4=BB=B6=E9=9B=B6=E5=BE=AA=E7=8E=AF=C2=B7awa?= =?UTF-8?q?it=E4=BB=85run()=E5=87=BD=E6=95=B0=E7=BA=A7=E4=B8=80=E5=A4=84aw?= =?UTF-8?q?ait=20=5Fbatch=5Ffinished;=E5=A4=B4=E6=B3=A8=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E5=A5=91=E7=BA=A6=E8=A1=8C+6=E4=B8=AArun=E6=9C=9F=E6=B4=BB?= =?UTF-8?q?=E6=88=90=E5=91=98;wd8=E4=B8=89=E6=96=AD=E8=A8=80=E9=9B=B6?= =?UTF-8?q?=E6=94=B9=E5=8A=A8=E4=BF=9D=E6=8C=81=E7=BB=BF+ui=5Ftune=5Fprobe?= =?UTF-8?q?=E5=85=A8=E9=93=BE=E8=B7=AFPASS=3DT0=E4=B8=A4=E9=9D=A2=E5=A4=8D?= =?UTF-8?q?=E6=A0=B8=E8=AF=BB=E6=95=B0(=E5=AE=9E=E7=8E=B0=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=C2=A75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/presentation/tune_sim_controller.gd | 50 +++++++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/game/presentation/tune_sim_controller.gd b/game/presentation/tune_sim_controller.gd index db2c5601..62a5c17e 100644 --- a/game/presentation/tune_sim_controller.gd +++ b/game/presentation/tune_sim_controller.gd @@ -2,16 +2,28 @@ ## 调整板批量模拟控制器:逐次驱动关卡自动策略(与 headless 扫描同口径),进度/报告经面板 setter 注入。 ## 零核心写——表基线复位由组合根在移交前完成,加成施加只走自动策略内部 runner.set_hero_override 单路径。 ## presentation 不 preload smoke:驱动实例由调用方注入(须供与 level_autoplay 同款 run_level 签名),缺省 null=运行时 load 兜底。 +## 逐帧步进:每局恰占一帧——第 0 局在调用点同步段执行,第 i 局(i≥1)在第 i 帧信号发射点执行,收尾恒在第 n 帧发射点; +## n=0 退化路径为调用点同步收尾零帧。 +## _batch_finished 信号契约:整批收尾放行——发射时点=报告注入与运行态复位之后;消费方=run() 自身收尾放行, +## 外部 await run(n) 经此挂起至整批完成(协程身份契约)。 extends RefCounted const SEED_BASE := 4200 # 模拟种子基(与历史实现同源——同种子可回放) const PlaytestLogger := preload("res://presentation/playtest_logger.gd") # 试玩日志(同层依赖——运行时 load 收敛为 preload 常量) +signal _batch_finished + var db var panel # 调试浮窗 setter 面:atk_pct/hp_pct/set_sim_running/set_sim_progress/set_sim_report var _base_hp := 0 # 报告中的"基础 HP"口径注记值 var _driver = null # 关卡自动策略驱动(调用方注入;null = 旧行为运行时 load 兜底) var _running := false # 运行态(run 全程 true——组合根互查守卫用,与面板置灰解耦) +var _sim_n := 0 # 本批局数(run 期活成员——批末失效、下次 run 重写) +var _sim_i := 0 # 已执行局数(步进计数) +var _sim_stats: Dictionary = {} # stats 六键束(run 期承载) +var _sim_autoplay = null # 自动策略驱动实例(run 期承载) +var _sim_logger = null # 共享 JSONL 日志会话(run 期承载) +var _finished := false # 批完成旗标(_finish_batch 置位——收尾段同步承载) func _init(db_ref, panel_ref, base_hp: int, driver = null) -> void: @@ -44,12 +56,38 @@ func run(n: int) -> void: panel.set_sim_progress("模拟中:0/%d …" % n) var stats := {"wins": 0, "dmg_all": [], "hp_left_win": [], "hp_boss": [], "rounds_all": [], "death_nodes": {}} var autoplay = _autoplay() - for i in range(n): - _run_one_level(autoplay, stats, i, panel, logger) - panel.set_sim_progress("模拟中:%d/%d …" % [i + 1, n]) - await panel.get_tree().process_frame - logger.close_session() - panel.set_sim_report(HudPresenter.tune_sim_report(n, panel.atk_pct(), panel.hp_pct(), stats, _base_hp)) + _sim_n = n + _sim_i = 0 + _sim_stats = stats + _sim_autoplay = autoplay + _sim_logger = logger + _finished = false + if n > 0: + if not panel.get_tree().process_frame.is_connected(_step_frame): + panel.get_tree().process_frame.connect(_step_frame) # 恰好连接一次(迭代 39 先例同款守卫) + _step_frame() # 首步同步执行(第 0 局在调用栈内跑完——与 await 形态对齐) + await _batch_finished + else: + _finish_batch() # n=0:循环零进同步收尾,不挂起(与 await 形态一致零帧) + + +# 逐帧步进回调:i void: + if _sim_i < _sim_n: + _run_one_level(_sim_autoplay, _sim_stats, _sim_i, panel, _sim_logger) + panel.set_sim_progress("模拟中:%d/%d …" % [_sim_i + 1, _sim_n]) + _sim_i += 1 + else: + panel.get_tree().process_frame.disconnect(_step_frame) # 先断连防再入 + _finish_batch() + _batch_finished.emit() + + +# 整批收尾单点(收尾四语句同帧同相位:close_session→报告→运行态复位——次序与 run() 尾现行形态逐句对齐) +func _finish_batch() -> void: + _finished = true + _sim_logger.close_session() + panel.set_sim_report(HudPresenter.tune_sim_report(_sim_n, panel.atk_pct(), panel.hp_pct(), _sim_stats, _base_hp)) panel.set_sim_running(false) _running = false