[Add] MVC UI for Yacht Dice scorecard
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>
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
public sealed class ScoreCardView : MonoBehaviour
|
||||
{
|
||||
[Header("Category Rows (in YachtCategory enum order)")]
|
||||
[SerializeField] private List<CategoryRowView> categoryRows = new();
|
||||
|
||||
[Header("Summary")]
|
||||
[SerializeField] private TMP_Text upperSumText;
|
||||
[SerializeField] private TMP_Text upperBonusText;
|
||||
[SerializeField] private TMP_Text totalScoreText;
|
||||
|
||||
public event Action<YachtCategory> OnCategorySelected;
|
||||
|
||||
private static readonly string[] CategoryNames =
|
||||
{
|
||||
"Единицы",
|
||||
"Двойки",
|
||||
"Тройки",
|
||||
"Четвёрки",
|
||||
"Пятёрки",
|
||||
"Шестёрки",
|
||||
"Тройка",
|
||||
"Каре",
|
||||
"Фулл-хаус",
|
||||
"Малый стрит",
|
||||
"Большой стрит",
|
||||
"Яхта",
|
||||
"Шанс"
|
||||
};
|
||||
|
||||
private YachtCategory[] allCategories;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
allCategories = (YachtCategory[])Enum.GetValues(typeof(YachtCategory));
|
||||
|
||||
for (int i = 0; i < categoryRows.Count && i < allCategories.Length; i++)
|
||||
{
|
||||
categoryRows[i].Initialize(allCategories[i], CategoryNames[i]);
|
||||
categoryRows[i].OnCategorySelected += HandleCategorySelected;
|
||||
}
|
||||
|
||||
UpdateTotalDisplay(0, 0, false);
|
||||
}
|
||||
|
||||
public void UpdatePreviews(Dictionary<YachtCategory, int> previews)
|
||||
{
|
||||
for (int i = 0; i < categoryRows.Count && i < allCategories.Length; i++)
|
||||
{
|
||||
if (previews.TryGetValue(allCategories[i], out int preview))
|
||||
{
|
||||
categoryRows[i].ShowPreview(preview);
|
||||
categoryRows[i].SetInteractable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearAllPreviews()
|
||||
{
|
||||
for (int i = 0; i < categoryRows.Count; i++)
|
||||
{
|
||||
categoryRows[i].HidePreview();
|
||||
categoryRows[i].SetInteractable(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCategoryScored(YachtCategory category, int score)
|
||||
{
|
||||
int index = (int)category;
|
||||
if (index >= 0 && index < categoryRows.Count)
|
||||
categoryRows[index].SetRecordedScore(score);
|
||||
}
|
||||
|
||||
public void SetAllInteractable(bool interactable)
|
||||
{
|
||||
for (int i = 0; i < categoryRows.Count; i++)
|
||||
categoryRows[i].SetInteractable(interactable);
|
||||
}
|
||||
|
||||
public void UpdateTotalDisplay(int totalScore, int upperSum, bool hasUpperBonus)
|
||||
{
|
||||
totalScoreText.text = totalScore.ToString();
|
||||
upperSumText.text = $"{upperSum} / 63";
|
||||
upperBonusText.text = hasUpperBonus ? "+35" : "---";
|
||||
}
|
||||
|
||||
public void ResetAll()
|
||||
{
|
||||
for (int i = 0; i < categoryRows.Count; i++)
|
||||
categoryRows[i].ResetRow();
|
||||
|
||||
UpdateTotalDisplay(0, 0, false);
|
||||
}
|
||||
|
||||
private void HandleCategorySelected(YachtCategory category)
|
||||
{
|
||||
OnCategorySelected?.Invoke(category);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
for (int i = 0; i < categoryRows.Count; i++)
|
||||
categoryRows[i].OnCategorySelected -= HandleCategorySelected;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user