# VERTICAL SLICE - NOT FOR PRODUCTION # Date: 2026-09-21 # 冒险全流程期望扫描(三关连探零加成基线批量试玩——run_adventure 的蒙特卡洛批量工具, # 补 level_monte_carlo 只测单关的空白面):固定 atk+0%/hp+0%(零天赋格加成,关间大奖励 # 按冒险结构现行设计自动兑付),逐局独立种子,输出: # ① 每局一行 RUNSUM JSON(stdout,局级摘要:策略/种子/result/summary/战斗轮数/承伤/踩雷/ # 刷新/行进序列/逐战上限序列——后续统计分析的取数面); # ② 全量操作日志 = playtest_logger 共享会话 JSONL(与真人试玩同合规口径,每策略一批一文件, # run 行携带种子/策略切分局次,落 user://logs/)。 # 本工具只采集与落盘数据,不做统计判读(通关率/败因分布归分析会话)。 # 运行:Godot_console.exe --headless --path . --script res://smoke/adventure_monte_carlo.gd -- [N] [seed0] [normal|perfect|both] [route min|max] extends SceneTree var _run_cursor := 0 # 全局局序号(seed = seed0 + cursor,逐局独立消费一次) func _initialize() -> void: var args := OS.get_cmdline_user_args() var n := 200 if args.size() >= 1 and args[0].is_valid_int(): n = maxi(5, int(args[0])) var seed0 := 71000 if args.size() >= 2 and args[1].is_valid_int(): seed0 = int(args[1]) var policy_arg := "both" if args.size() >= 3 and args[2] in ["normal", "perfect", "both"]: policy_arg = args[2] var policies: Array = ["normal"] if policy_arg == "perfect": policies = ["perfect"] elif policy_arg == "both": policies = ["normal", "perfect"] var route := "min" if args.size() >= 4 and args[3] in ["min", "max"]: route = args[3] var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("表加载失败") quit(1) return var autoplay = load("res://smoke/level_autoplay.gd") var t0 := Time.get_ticks_msec() print("=== 冒险全流程扫描:三关连探 · N=%d/策略 · 种子 %d 起逐局独立 · 策略=%s · atk+0%%/hp+0%% 零加成 · route=%s ===" % [n, seed0, policy_arg, route]) for policy in policies: # 每策略一个共享日志会话(全量 JSONL 体量随局数增长,分文件便于定位) var logger = load("res://presentation/playtest_logger.gd").new() logger.ap_per_round = int(db.action_economy.ap_per_round) var log_path: String = logger.start_session(seed0) var tally := {} for i in range(n): var seed_val := seed0 + _run_cursor _run_cursor += 1 var st = autoplay.run_adventure(db, seed_val, 0, 0, false, logger, policy, route) var sum: Dictionary = st["summary"] var rec := { "policy": policy, "seed": seed_val, "atk_pct": 0, "hp_pct": 0, "route": route, "result": st["result"], "cleared": bool(sum.get("cleared", false)), "levels_cleared": int(sum.get("levels_cleared", -1)), "stopped_at": int(sum.get("stopped_at", -1)), "keystone_total": int(sum.get("keystone_total", -1)), "battles": int(st["battles"]), "rounds": int(st["rounds"]), "hero_dmg": int(st["hero_dmg"]), "mine_hits": int(st["mine_hits"]), "refreshes": int(st["refreshes"]), "choices": int(st["choices"]), "visited_count": (st["visited_ids"] as Array).size(), "encounter_max_hp_seq": st["encounter_max_hp_seq"], "reward_events": st["reward_events"], "shop_gp_seq": st["shop_gp_seq"], "level_templates": st.get("level_templates", []), "wallet_count": (st["wallet_events"] as Array).size(), } var rs := String(sum.get("result", "")) tally[rs] = int(tally.get(rs, 0)) + 1 print("RUNSUM " + JSON.stringify(rec)) if (i + 1) % 20 == 0: print("... %s 进度 %d/%d(耗时 %.1f 秒)" % [policy, i + 1, n, float(Time.get_ticks_msec() - t0) / 1000.0]) logger.close_session() print("BATCH %s N=%d 终局计数=%s 日志=%s" % [policy, n, JSON.stringify(tally), log_path]) print("(口径注:零加成 = atk/hp 天赋格百分比均 0;关间大奖励(HP 上限提升+回满)按冒险结构设计自动兑付,未额外剥离 · 全程日志见 user://logs/ · 总耗时 %.1f 秒)" % [float(Time.get_ticks_msec() - t0) / 1000.0]) quit(0)