using System; using System.Collections.Generic; using UnityEngine; using Colosseum.AI.BehaviorActions.Conditions; namespace Colosseum.AI { /// /// 가중치 기반 패턴 선택 후보를 표현합니다. /// public readonly struct WeightedPatternCandidate { public WeightedPatternCandidate(BossPatternData pattern, float weight) { Pattern = pattern; Weight = weight; } public BossPatternData Pattern { get; } public float Weight { get; } } /// /// 준비된 패턴 후보 중 하나를 가중치 기반으로 선택합니다. /// public static class WeightedPatternSelector { public static bool HasAnyReadyPattern(GameObject owner, IReadOnlyList candidates) { if (owner == null || candidates == null) return false; for (int i = 0; i < candidates.Count; i++) { WeightedPatternCandidate candidate = candidates[i]; if (candidate.Pattern == null || candidate.Weight <= 0f) continue; if (PatternReadyHelper.IsPatternReady(owner, candidate.Pattern)) return true; } return false; } public static bool TrySelectReadyPattern(GameObject owner, IReadOnlyList candidates, out BossPatternData selectedPattern) { if (owner == null) { selectedPattern = null; return false; } return TrySelectPattern( candidates, pattern => PatternReadyHelper.IsPatternReady(owner, pattern), UnityEngine.Random.value, out selectedPattern); } public static bool TrySelectPattern( IReadOnlyList candidates, Predicate isPatternReady, float normalizedRoll, out BossPatternData selectedPattern) { selectedPattern = null; if (candidates == null || isPatternReady == null) return false; List readyCandidates = new List(candidates.Count); float totalWeight = 0f; for (int i = 0; i < candidates.Count; i++) { WeightedPatternCandidate candidate = candidates[i]; if (candidate.Pattern == null || candidate.Weight <= 0f) continue; if (!isPatternReady(candidate.Pattern)) continue; readyCandidates.Add(candidate); totalWeight += candidate.Weight; } if (readyCandidates.Count == 0 || totalWeight <= 0f) return false; float clampedRoll = Mathf.Clamp01(normalizedRoll); float targetWeight = clampedRoll >= 1f ? totalWeight : totalWeight * clampedRoll; float cumulativeWeight = 0f; for (int i = 0; i < readyCandidates.Count; i++) { WeightedPatternCandidate candidate = readyCandidates[i]; cumulativeWeight += candidate.Weight; if (targetWeight < cumulativeWeight || i == readyCandidates.Count - 1) { selectedPattern = candidate.Pattern; return true; } } return false; } } }