Files
gplan-2/game/sim/reward_expectation.gd
T

96 lines
3.4 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
# 奖励期望测量:逐深度实测 |非封锁格|(safe ∪ mines ∖ R₀)分布、格面资源类型频次
# (应涌现自正向行九型权重 attack 14 / defense 11 / blast 16 / heal 4 / weaken 8 / pierce 8 / magic 8 / action 6 / gp 2,合计 77——reward.tres 现行)、
# 封锁格零泄漏(R₀ 格不在摇号清单)——走真实 地图战斗资源.roll_board 管线。
# 运行:Godot_console.exe --headless --path . --script res://sim/reward_expectation.gd
extends SceneTree
const N := 200
func _initialize() -> void:
var db = load("res://core/config_db.gd").new()
if not db.load_tables("res://data/tables", false):
print("表加载失败")
quit(1)
return
var board_generator = load("res://core/board_generator.gd").new()
var reward_economy_factory = load("res://core/reward_economy.gd")
var rng_factory = load("res://core/rng_service.gd")
var types := ["attack", "defense", "heal", "blast", "weaken"]
print("=== 奖励期望测量(格面资源批 · N=%d 板/深度)===" % N)
print("depth | 非封锁格均/min/max | attack% | defense% | heal% | blast% | weaken% | 封锁格泄漏板")
for depth in range(5):
var elig: Array = []
var type_counts := {"attack": 0.0, "defense": 0.0, "heal": 0.0, "blast": 0.0, "weaken": 0.0}
var leak := 0
for i in range(N):
var rng = rng_factory.new()
rng.set_master_seed(90000 + depth * 1000 + i)
var board = board_generator.generate(1, depth, rng.open_stream("board_gen"), db)
if board == null:
continue
var r0 := {}
for c in board.compute_r0():
r0[c] = true
var eligible: Array = []
for c in board.safe_cells():
if not r0.has(c):
eligible.append(c)
for c in board.mines.keys():
if not r0.has(c):
eligible.append(c)
elig.append(eligible.size())
var reward_economy = reward_economy_factory.new(db, rng)
var list: Array = []
for c in eligible:
list.append({"cell": c})
if not reward_economy.roll_board(list):
continue
# 封锁格零泄漏:R₀ 格必不在映射(is_mapped 静默查询——零诊断噪音)
var r0_listed := false
for c in r0.keys():
if reward_economy.is_mapped(c):
r0_listed = true
if r0_listed:
leak += 1
for c in eligible:
var ident = reward_economy.query_identity(c)
if ident != null:
type_counts[String(ident.cell_type)] += 1.0
var total := 0.0
for t in types:
total += type_counts[t]
print("D%d %dx%d | %6.1f / %3d / %3d | %5.1f%% | %6.1f%% | %4.1f%% | %5.1f%% | %6.1f%% | %d" % [
depth, 10 if depth <= 1 else 12, 10 if depth <= 1 else 12,
_mean(elig), _min(elig), _max(elig),
100.0 * type_counts.attack / total, 100.0 * type_counts.defense / total,
100.0 * type_counts.heal / total, 100.0 * type_counts.blast / total,
100.0 * type_counts.weaken / total, leak])
print("(口径:类型频次 = 正向行权重涌现——attack 25.3%% / defense 20.3%% / blast 20.3%% / heal 19.0%% / weaken 15.2%%;")
print(" 非封锁格 = safe ∪ mines ∖ R₀,雷安同池同分布;封锁格泄漏 = R₀ 格 query_identity 非 null 的板数,恒应为 0)")
quit(0)
func _mean(a: Array) -> float:
if a.is_empty():
return 0.0
var t := 0.0
for v in a:
t += float(v)
return t / a.size()
func _min(a: Array) -> int:
var m := 99999
for v in a:
m = mini(m, int(v))
return m
func _max(a: Array) -> int:
var m := 0
for v in a:
m = maxi(m, int(v))
return m