using System; using System.Collections.Generic; using UnityEngine; public sealed class ScoringSystem : MonoBehaviour { public event Action OnCategoryScored; public event Action OnAllCategoriesScored; public event Action OnCategoryConfirmed; private readonly Dictionary scorecard = new(); private readonly HashSet usedCategories = new(); private List activeModifierData = new(); public bool IsCategoryUsed(YachtCategory category) => usedCategories.Contains(category); public int GetCategoryScore(YachtCategory category) { return scorecard.TryGetValue(category, out int score) ? score : -1; } public int TotalScore { get { int total = 0; foreach (var kvp in scorecard) total += kvp.Value; return total; } } public int CategoriesFilledCount => usedCategories.Count; public int TotalCategoryCount => Enum.GetValues(typeof(YachtCategory)).Length; public bool IsComplete => CategoriesFilledCount >= TotalCategoryCount; public void SetActiveModifiers(List modifiers) { activeModifierData = modifiers ?? new List(); } public IReadOnlyList ActiveModifiers => activeModifierData; public ScoreResult PreviewScore(int[] diceValues, YachtCategory category) { int baseScore = CategoryScorer.Calculate(diceValues, category); ScoreResult result = ScoreResult.Create(baseScore, diceValues, category); ModifierPipeline.Apply(activeModifierData, ref result, ModifierScope.SelectedCategory); return result; } public ScoreResult ScoreCategory(int[] diceValues, YachtCategory category) { if (usedCategories.Contains(category)) throw new InvalidOperationException($"Category {category} has already been scored."); int baseScore = CategoryScorer.Calculate(diceValues, category); ScoreResult result = ScoreResult.Create(baseScore, diceValues, category); ModifierPipeline.Apply(activeModifierData, ref result, ModifierScope.SelectedCategory); ModifierPipeline.Apply(activeModifierData, ref result, ModifierScope.AnyCategoryClosed); int finalScore = result.FinalScore; scorecard[category] = finalScore; usedCategories.Add(category); OnCategoryScored?.Invoke(category, finalScore); OnCategoryConfirmed?.Invoke(category, result); if (IsComplete) OnAllCategoriesScored?.Invoke(TotalScore); return result; } public void ResetScorecard() { scorecard.Clear(); usedCategories.Clear(); } }