[Refactor] Replace hardcoded categories with data-driven SO system and abstract dice
- Add abstract dice system (IDie interface, DieDefinitionSO, StandardDieSO, DieInstance) to support future custom dice types while keeping backward compat via int[] DiceValues - Replace YachtCategory enum and CategoryScorer switch with CategoryDefinitionSO hierarchy: SumOfValueCategorySO, NOfAKindCategorySO, FullHouseCategorySO, StraightCategorySO, SumAllCategorySO - Add CategoryCatalogSO for ordered category collections and DiceCheckUtility for shared logic - Refactor ScoringSystem, Views, GameManager, GameController to use SO references - Update CategoryCondition modifier to use SO reference instead of enum - Update all editor tests to use SO-based categories and DieInstance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,32 +14,37 @@ namespace YachtDice.Game
|
||||
|
||||
public int DiceCount => diceRollers.Count;
|
||||
|
||||
private bool[] locked;
|
||||
private int[] currentValues;
|
||||
private DieInstance[] diceInstances;
|
||||
private int pendingCount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
int count = diceRollers.Count;
|
||||
locked = new bool[count];
|
||||
currentValues = new int[count];
|
||||
diceInstances = new DieInstance[count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var definition = diceRollers[i].Definition;
|
||||
diceInstances[i] = new DieInstance(definition);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLocked(int index) => locked[index];
|
||||
public bool IsLocked(int index) => diceInstances[index].IsLocked;
|
||||
|
||||
public void ToggleLock(int index)
|
||||
{
|
||||
locked[index] = !locked[index];
|
||||
diceInstances[index].IsLocked = !diceInstances[index].IsLocked;
|
||||
}
|
||||
|
||||
public void SetLocked(int index, bool isLocked)
|
||||
{
|
||||
locked[index] = isLocked;
|
||||
diceInstances[index].IsLocked = isLocked;
|
||||
}
|
||||
|
||||
public void UnlockAll()
|
||||
{
|
||||
for (int i = 0; i < locked.Length; i++) locked[i] = false;
|
||||
for (int i = 0; i < diceInstances.Length; i++)
|
||||
diceInstances[i].IsLocked = false;
|
||||
}
|
||||
|
||||
public void RollUnlocked()
|
||||
@@ -51,7 +56,7 @@ namespace YachtDice.Game
|
||||
|
||||
for (int i = 0; i < diceRollers.Count; i++)
|
||||
{
|
||||
if (locked[i]) continue;
|
||||
if (diceInstances[i].IsLocked) continue;
|
||||
|
||||
pendingCount++;
|
||||
int capturedIndex = i;
|
||||
@@ -59,7 +64,7 @@ namespace YachtDice.Game
|
||||
void Handler(int value)
|
||||
{
|
||||
diceRollers[capturedIndex].OnRollFinished -= Handler;
|
||||
currentValues[capturedIndex] = value;
|
||||
diceInstances[capturedIndex].Value = value;
|
||||
OnDieSettled?.Invoke(capturedIndex, value);
|
||||
|
||||
pendingCount--;
|
||||
@@ -75,14 +80,19 @@ namespace YachtDice.Game
|
||||
OnAllDiceSettled?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>Возвращает абстрактный список дайсов (основной API).</summary>
|
||||
public IReadOnlyList<IDie> GetDice() => diceInstances;
|
||||
|
||||
/// <summary>Возвращает копию текущих значений (обратная совместимость).</summary>
|
||||
public int[] GetCurrentValues()
|
||||
{
|
||||
int[] copy = new int[currentValues.Length];
|
||||
Array.Copy(currentValues, copy, currentValues.Length);
|
||||
return copy;
|
||||
int[] values = new int[diceInstances.Length];
|
||||
for (int i = 0; i < diceInstances.Length; i++)
|
||||
values[i] = diceInstances[i].Value;
|
||||
return values;
|
||||
}
|
||||
|
||||
public int GetValue(int index) => currentValues[index];
|
||||
public int GetValue(int index) => diceInstances[index].Value;
|
||||
|
||||
public bool IsAnyRolling
|
||||
{
|
||||
@@ -100,7 +110,7 @@ namespace YachtDice.Game
|
||||
{
|
||||
var diceComponent = diceRollers[i].GetComponent<Dice.Dice>();
|
||||
if (diceComponent != null && diceComponent.TryGetTopValue(out int val))
|
||||
currentValues[i] = val;
|
||||
diceInstances[i].Value = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user