using System; using UnityEngine; using VContainer; using YachtDice.Categories; using YachtDice.Scoring; namespace YachtDice.Game { public class GameLoopController : MonoBehaviour { [Header("Settings")] [SerializeField] private int maxRollsPerTurn = 3; private DiceManager _diceManager; private ScoringSystem _scoringSystem; public int CurrentRoll { get; private set; } public int CurrentTurn { get; private set; } public int MaxRollsPerTurn => maxRollsPerTurn; public bool CanRoll => CurrentRoll < maxRollsPerTurn && !_diceManager.IsAnyRolling; public bool CanScore => CurrentRoll > 0 && !_diceManager.IsAnyRolling; public bool IsGameOver => _scoringSystem.IsComplete; public event Action OnTurnStarted; public event Action OnRollComplete; public event Action OnScored; public event Action OnGameOver; [Inject] public void Construct(DiceManager diceManager, ScoringSystem scoringSystem) { this._diceManager = diceManager; this._scoringSystem = scoringSystem; } public void StartNewGame() { _scoringSystem.ResetScorecard(); CurrentTurn = 0; StartNewTurn(); } private void StartNewTurn() { CurrentTurn++; CurrentRoll = 0; _diceManager.UnlockAll(); OnTurnStarted?.Invoke(CurrentTurn); } public void Roll() { if (!CanRoll) return; CurrentRoll++; _diceManager.OnAllDiceSettled += HandleAllDiceSettled; _diceManager.RollUnlocked(); } private void HandleAllDiceSettled() { _diceManager.OnAllDiceSettled -= HandleAllDiceSettled; OnRollComplete?.Invoke(CurrentRoll); } public void ToggleDiceLock(int index) { if (_diceManager.IsAnyRolling) return; if (CurrentRoll == 0) return; _diceManager.ToggleLock(index); } public void ScoreInCategory(CategoryDefinition category) { if (!CanScore) return; if (_scoringSystem.IsCategoryUsed(category)) return; var dice = _diceManager.GetDice(); var result = _scoringSystem.ScoreCategory(dice, category); OnScored?.Invoke(category, result.FinalScore); if (_scoringSystem.IsComplete) { var total = _scoringSystem.TotalScore; OnGameOver?.Invoke(total); } else { StartNewTurn(); } } } }