d06ad78645
View layer: CategoryRowView (reusable x13 row with preview/recorded score display), ScoreCardView (full scorecard panel with Russian category names, upper bonus tracking), DicePanelView (5 dice buttons with lock toggle + roll counter), GameInfoView (turn display + game over overlay). Controller layer: GameController bridges Model and View — subscribes to model events in Awake() to catch GameManager.Start(), routes UI clicks to game logic, computes preview scores for all unfilled categories after each roll, handles upper section bonus (63+ = +35). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
198 lines
6.4 KiB
C#
198 lines
6.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public sealed class GameController : MonoBehaviour
|
|
{
|
|
[Header("Model")]
|
|
[SerializeField] private GameManager gameManager;
|
|
[SerializeField] private ScoringSystem scoringSystem;
|
|
[SerializeField] private DiceManager diceManager;
|
|
|
|
[Header("Views")]
|
|
[SerializeField] private ScoreCardView scoreCardView;
|
|
[SerializeField] private DicePanelView dicePanelView;
|
|
[SerializeField] private GameInfoView gameInfoView;
|
|
|
|
[Header("Settings")]
|
|
[SerializeField] private int maxRollsPerTurn = 3;
|
|
|
|
private static readonly YachtCategory[] UpperCategories =
|
|
{
|
|
YachtCategory.Ones, YachtCategory.Twos, YachtCategory.Threes,
|
|
YachtCategory.Fours, YachtCategory.Fives, YachtCategory.Sixes
|
|
};
|
|
|
|
private const int UpperBonusThreshold = 63;
|
|
private const int UpperBonusValue = 35;
|
|
|
|
private int totalCategoryCount;
|
|
|
|
// ── Lifecycle ──────────────────────────────────────────────
|
|
|
|
private void Awake()
|
|
{
|
|
totalCategoryCount = Enum.GetValues(typeof(YachtCategory)).Length;
|
|
|
|
// Model → Controller
|
|
gameManager.OnTurnStarted += HandleTurnStarted;
|
|
gameManager.OnRollComplete += HandleRollComplete;
|
|
gameManager.OnScored += HandleScored;
|
|
gameManager.OnGameOver += HandleGameOver;
|
|
diceManager.OnDieSettled += HandleDieSettled;
|
|
|
|
// View → Controller
|
|
scoreCardView.OnCategorySelected += HandleCategorySelected;
|
|
dicePanelView.OnRollClicked += HandleRollClicked;
|
|
dicePanelView.OnDiceToggled += HandleDiceToggled;
|
|
gameInfoView.OnNewGameClicked += HandleNewGameClicked;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
gameManager.OnTurnStarted -= HandleTurnStarted;
|
|
gameManager.OnRollComplete -= HandleRollComplete;
|
|
gameManager.OnScored -= HandleScored;
|
|
gameManager.OnGameOver -= HandleGameOver;
|
|
diceManager.OnDieSettled -= HandleDieSettled;
|
|
|
|
scoreCardView.OnCategorySelected -= HandleCategorySelected;
|
|
dicePanelView.OnRollClicked -= HandleRollClicked;
|
|
dicePanelView.OnDiceToggled -= HandleDiceToggled;
|
|
gameInfoView.OnNewGameClicked -= HandleNewGameClicked;
|
|
}
|
|
|
|
// ── Model Event Handlers ──────────────────────────────────
|
|
|
|
private void HandleTurnStarted(int turn)
|
|
{
|
|
gameInfoView.SetTurnText(turn, totalCategoryCount);
|
|
dicePanelView.ResetForNewTurn();
|
|
dicePanelView.SetRollButtonState(true, 0, maxRollsPerTurn);
|
|
scoreCardView.ClearAllPreviews();
|
|
}
|
|
|
|
private void HandleRollComplete(int rollNumber)
|
|
{
|
|
bool canRollAgain = gameManager.CanRoll;
|
|
dicePanelView.SetRollButtonState(canRollAgain, rollNumber, maxRollsPerTurn);
|
|
dicePanelView.SetDiceInteractable(true);
|
|
|
|
int[] values = diceManager.GetCurrentValues();
|
|
dicePanelView.SetAllDiceValues(values);
|
|
|
|
UpdatePreviewScores(values);
|
|
}
|
|
|
|
private void HandleDieSettled(int index, int value)
|
|
{
|
|
dicePanelView.SetDieValue(index, value);
|
|
}
|
|
|
|
private void HandleScored(YachtCategory category, int finalScore)
|
|
{
|
|
scoreCardView.SetCategoryScored(category, finalScore);
|
|
UpdateTotalDisplay();
|
|
}
|
|
|
|
private void HandleGameOver(int totalScore)
|
|
{
|
|
dicePanelView.SetRollButtonState(false, maxRollsPerTurn, maxRollsPerTurn);
|
|
dicePanelView.SetDiceInteractable(false);
|
|
scoreCardView.SetAllInteractable(false);
|
|
|
|
int displayTotal = CalculateDisplayTotal();
|
|
gameInfoView.ShowGameOver(displayTotal);
|
|
}
|
|
|
|
// ── View Event Handlers ───────────────────────────────────
|
|
|
|
private void HandleRollClicked()
|
|
{
|
|
if (!gameManager.CanRoll) return;
|
|
|
|
dicePanelView.SetRollButtonState(false, gameManager.CurrentRoll, maxRollsPerTurn);
|
|
dicePanelView.SetDiceInteractable(false);
|
|
scoreCardView.SetAllInteractable(false);
|
|
|
|
gameManager.Roll();
|
|
}
|
|
|
|
private void HandleDiceToggled(int index)
|
|
{
|
|
if (gameManager.CurrentRoll == 0) return;
|
|
if (diceManager.IsAnyRolling) return;
|
|
|
|
gameManager.ToggleDiceLock(index);
|
|
|
|
bool isLocked = diceManager.IsLocked(index);
|
|
dicePanelView.SetDieLocked(index, isLocked);
|
|
}
|
|
|
|
private void HandleCategorySelected(YachtCategory category)
|
|
{
|
|
if (!gameManager.CanScore) return;
|
|
if (scoringSystem.IsCategoryUsed(category)) return;
|
|
|
|
gameManager.ScoreInCategory(category);
|
|
}
|
|
|
|
private void HandleNewGameClicked()
|
|
{
|
|
gameInfoView.HideGameOver();
|
|
scoreCardView.ResetAll();
|
|
dicePanelView.ResetForNewGame();
|
|
gameManager.StartNewGame();
|
|
}
|
|
|
|
// ── Helpers ────────────────────────────────────────────────
|
|
|
|
private void UpdatePreviewScores(int[] diceValues)
|
|
{
|
|
var previews = new Dictionary<YachtCategory, int>();
|
|
var categories = (YachtCategory[])Enum.GetValues(typeof(YachtCategory));
|
|
|
|
for (int i = 0; i < categories.Length; i++)
|
|
{
|
|
if (scoringSystem.IsCategoryUsed(categories[i])) continue;
|
|
|
|
ScoreResult result = scoringSystem.PreviewScore(diceValues, categories[i]);
|
|
previews[categories[i]] = result.FinalScore;
|
|
}
|
|
|
|
scoreCardView.UpdatePreviews(previews);
|
|
}
|
|
|
|
private void UpdateTotalDisplay()
|
|
{
|
|
int upperSum = 0;
|
|
for (int i = 0; i < UpperCategories.Length; i++)
|
|
{
|
|
int catScore = scoringSystem.GetCategoryScore(UpperCategories[i]);
|
|
if (catScore >= 0) upperSum += catScore;
|
|
}
|
|
|
|
bool hasBonus = upperSum >= UpperBonusThreshold;
|
|
int displayTotal = CalculateDisplayTotal();
|
|
|
|
scoreCardView.UpdateTotalDisplay(displayTotal, upperSum, hasBonus);
|
|
}
|
|
|
|
private int CalculateDisplayTotal()
|
|
{
|
|
int total = scoringSystem.TotalScore;
|
|
|
|
int upperSum = 0;
|
|
for (int i = 0; i < UpperCategories.Length; i++)
|
|
{
|
|
int catScore = scoringSystem.GetCategoryScore(UpperCategories[i]);
|
|
if (catScore >= 0) upperSum += catScore;
|
|
}
|
|
|
|
if (upperSum >= UpperBonusThreshold)
|
|
total += UpperBonusValue;
|
|
|
|
return total;
|
|
}
|
|
}
|