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;
}
}
}