using System; using System.Collections.Generic; using System.Globalization; using UnityEngine; namespace TKS { /// /// 적 AI 점수 가중치(PD #1098 · 전술규칙_적AI_기획서 §2-3 · SOT = Assets/Data/AI/ai_weights.csv = 기획 tables/ 사본) → /// Resources/AI/AiWeights(메뉴 TKS/Import Gimmicks 가 함께 임포트). 코드는 키 이름만 안다(C45). /// public class AiWeights : ScriptableObject { public const string CsvPath = "Data/AI/ai_weights.csv"; // Assets/ 아래 public const string ResourcePath = "AI/AiWeights"; /// 코드가 읽는 키(표에 없으면 임포트 오류). public static readonly string[] Keys = { "dmg_player", "kill_base", "kill_hp_ratio", "dmg_own", "gimmick_dest_bonus", "chain", "support_reach", "pierce_hit", "archer_cover", "high_ground", "cav_line", "splash_hit", "route_open", "zone_end", "banner", "skill_waste", "approach", "boss_accuracy", "mode_accuracy", "noise_power", "top_n", "dirs", "dirs_many", "many_units", "power_1", "power_2", "power_3", "budget_ms", "boss_active", "active_max_chapter" }; [Serializable] public class Entry { public string key; public float value; public string desc; } public List entries = new List(); Dictionary index; public float this[string key] { get { if (index == null) { index = new Dictionary(); foreach (var e in entries) index[e.key] = e.value; } float v; if (index.TryGetValue(key, out v)) return v; Debug.LogError("[TKS] ai_weights.csv 에 키 없음: " + key); return 0f; } } static AiWeights cached; public static AiWeights Load() { if (cached == null) cached = Resources.Load(ResourcePath); return cached; } public static void Invalidate() { cached = null; } /// CSV(key,value,desc_ko) 해석 · 키 누락·숫자 아님 = errors. public static List Parse(string text, List errors) { var list = new List(); var seen = new HashSet(); foreach (var r in StageTable.ReadCsv(text, "ai_weights.csv", errors)) { string k, v, d; r.TryGetValue("key", out k); r.TryGetValue("value", out v); r.TryGetValue("desc_ko", out d); float f; if (string.IsNullOrEmpty(k) || !float.TryParse(v, NumberStyles.Float, CultureInfo.InvariantCulture, out f)) { errors.Add("ai_weights.csv 줄 " + r["#"] + ": key·value 형식(「" + k + "」 · 「" + v + "」)"); continue; } if (!seen.Add(k)) errors.Add("ai_weights.csv 줄 " + r["#"] + ": key 중복 「" + k + "」"); list.Add(new Entry { key = k, value = f, desc = d ?? "" }); } foreach (var k in Keys) { if (!seen.Contains(k)) errors.Add("ai_weights.csv: 키 없음 「" + k + "」"); } return list; } } }