[Add] GameLoop base
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using YachtDice.Categories;
|
||||
using YachtDice.Dice;
|
||||
using YachtDice.Economy;
|
||||
using YachtDice.Run;
|
||||
using YachtDice.Scoring;
|
||||
|
||||
namespace YachtDice.Tests
|
||||
{
|
||||
public sealed class RunLoopServiceTests
|
||||
{
|
||||
private readonly List<Object> _createdAssets = new();
|
||||
private readonly IReadOnlyList<IDice> _emptyDice = new IDice[0];
|
||||
|
||||
private CurrencyBank _currencyBank;
|
||||
private ScoringSystem _scoringSystem;
|
||||
private StoredRollBank _storedRollBank;
|
||||
private RunBalanceConfigSO _config;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
var bankGo = new GameObject("CurrencyBank");
|
||||
_currencyBank = bankGo.AddComponent<CurrencyBank>();
|
||||
_currencyBank.SetBalance(0);
|
||||
|
||||
var scoringGo = new GameObject("ScoringSystem");
|
||||
_scoringSystem = scoringGo.AddComponent<ScoringSystem>();
|
||||
|
||||
_storedRollBank = new StoredRollBank();
|
||||
_config = RunBalanceConfigSO.CreateDefault();
|
||||
_createdAssets.Add(_config);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
foreach (var scoring in Object.FindObjectsByType<ScoringSystem>(FindObjectsSortMode.None))
|
||||
Object.DestroyImmediate(scoring.gameObject);
|
||||
|
||||
foreach (var bank in Object.FindObjectsByType<CurrencyBank>(FindObjectsSortMode.None))
|
||||
Object.DestroyImmediate(bank.gameObject);
|
||||
|
||||
for (var i = 0; i < _createdAssets.Count; i++)
|
||||
{
|
||||
if (_createdAssets[i] != null)
|
||||
Object.DestroyImmediate(_createdAssets[i]);
|
||||
}
|
||||
|
||||
_createdAssets.Clear();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StartNewRun_EntersShopWithConfigQuota()
|
||||
{
|
||||
var categories = CreateFixedCatalog(100, 100, 100);
|
||||
var service = CreateService(categories);
|
||||
|
||||
service.StartNewRun();
|
||||
|
||||
Assert.AreEqual(30, service.State.BaseQuota);
|
||||
Assert.AreEqual(1, service.State.BetIndex);
|
||||
Assert.AreEqual(RunPhase.Shop, service.State.Phase);
|
||||
Assert.AreEqual(0, service.State.StoredRolls);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearedStage_AwardsCurrencyAndBanksUnusedRolls()
|
||||
{
|
||||
var categories = CreateFixedCatalog(100, 100, 100);
|
||||
var service = CreateService(categories);
|
||||
|
||||
service.StartNewRun();
|
||||
service.CompleteShop();
|
||||
service.TryBeginRoll();
|
||||
service.NotifyRollResolved(_emptyDice);
|
||||
|
||||
var cleared = service.TryScoreCategoryAsync(_emptyDice, categories.All[0]).GetAwaiter().GetResult();
|
||||
|
||||
Assert.IsTrue(cleared);
|
||||
Assert.AreEqual(25, _currencyBank.Balance);
|
||||
Assert.AreEqual(2, service.State.StoredRolls);
|
||||
Assert.AreEqual(2, service.State.StageNumber);
|
||||
Assert.AreEqual(RunPhase.StageStart, service.State.Phase);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoredRolls_CanBeConsumedOnLaterStage()
|
||||
{
|
||||
var categories = CreateFixedCatalog(100, 100, 100);
|
||||
var service = CreateService(categories);
|
||||
|
||||
service.StartNewRun();
|
||||
service.CompleteShop();
|
||||
service.TryBeginRoll();
|
||||
service.NotifyRollResolved(_emptyDice);
|
||||
service.TryScoreCategoryAsync(_emptyDice, categories.All[0]).GetAwaiter().GetResult();
|
||||
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
Assert.IsTrue(service.TryBeginRoll());
|
||||
service.NotifyRollResolved(_emptyDice);
|
||||
}
|
||||
|
||||
service.TryScoreCategoryAsync(_emptyDice, categories.All[1]).GetAwaiter().GetResult();
|
||||
|
||||
Assert.AreEqual(1, service.State.StoredRolls);
|
||||
Assert.AreEqual(50, _currencyBank.Balance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompletedCycle_GrantsBonusRaisesQuotaAndStartsNextBet()
|
||||
{
|
||||
var categories = CreateFixedCatalog(100, 100, 100);
|
||||
var service = CreateService(categories);
|
||||
|
||||
service.StartNewRun();
|
||||
service.CompleteShop();
|
||||
|
||||
ClearStageInOneRoll(service, categories.All[0]);
|
||||
ClearStageInOneRoll(service, categories.All[1]);
|
||||
ClearStageInOneRoll(service, categories.All[2]);
|
||||
|
||||
Assert.AreEqual(135, _currencyBank.Balance);
|
||||
Assert.AreEqual(60, service.State.BaseQuota);
|
||||
Assert.AreEqual(2, service.State.BetIndex);
|
||||
Assert.AreEqual(RunPhase.Shop, service.State.Phase);
|
||||
Assert.AreEqual(6, service.State.StoredRolls);
|
||||
Assert.AreEqual(0, _scoringSystem.CategoriesFilledCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FailedStage_EndsRunWhenNoTargetCanBeMet()
|
||||
{
|
||||
var categories = CreateFixedCatalog(10);
|
||||
var service = CreateService(categories);
|
||||
|
||||
service.StartNewRun();
|
||||
service.CompleteShop();
|
||||
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
Assert.IsTrue(service.TryBeginRoll());
|
||||
service.NotifyRollResolved(_emptyDice);
|
||||
}
|
||||
|
||||
Assert.IsTrue(service.State.IsFailed);
|
||||
Assert.AreEqual(RunPhase.RunFailed, service.State.Phase);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Shop_ReopensOnlyAtStartOfNextBet()
|
||||
{
|
||||
var categories = CreateFixedCatalog(100, 100, 100, 100);
|
||||
var service = CreateService(categories);
|
||||
|
||||
service.StartNewRun();
|
||||
Assert.AreEqual(RunPhase.Shop, service.State.Phase);
|
||||
|
||||
service.CompleteShop();
|
||||
ClearStageInOneRoll(service, categories.All[0]);
|
||||
Assert.AreEqual(RunPhase.StageStart, service.State.Phase);
|
||||
|
||||
ClearStageInOneRoll(service, categories.All[1]);
|
||||
Assert.AreEqual(RunPhase.StageStart, service.State.Phase);
|
||||
|
||||
ClearStageInOneRoll(service, categories.All[2]);
|
||||
Assert.AreEqual(RunPhase.Shop, service.State.Phase);
|
||||
Assert.AreEqual(2, service.State.BetIndex);
|
||||
}
|
||||
|
||||
private RunLoopService CreateService(CategoryCatalog catalog)
|
||||
{
|
||||
_scoringSystem.Construct(null, null, catalog, _currencyBank);
|
||||
return new RunLoopService(_config, _scoringSystem, _currencyBank, _storedRollBank);
|
||||
}
|
||||
|
||||
private CategoryCatalog CreateFixedCatalog(params int[] scores)
|
||||
{
|
||||
var categories = new List<CategoryDefinition>();
|
||||
for (var i = 0; i < scores.Length; i++)
|
||||
{
|
||||
var category = FixedScoreCategory.Create($"cat_{i}", scores[i]);
|
||||
_createdAssets.Add(category);
|
||||
categories.Add(category);
|
||||
}
|
||||
|
||||
var catalog = CategoryCatalog.CreateForTest(categories);
|
||||
_createdAssets.Add(catalog);
|
||||
return catalog;
|
||||
}
|
||||
|
||||
private void ClearStageInOneRoll(RunLoopService service, CategoryDefinition category)
|
||||
{
|
||||
Assert.IsTrue(service.TryBeginRoll());
|
||||
service.NotifyRollResolved(_emptyDice);
|
||||
Assert.IsTrue(service.TryScoreCategoryAsync(_emptyDice, category).GetAwaiter().GetResult());
|
||||
}
|
||||
|
||||
private sealed class FixedScoreCategory : CategoryDefinition
|
||||
{
|
||||
[SerializeField] private int fixedScore;
|
||||
|
||||
public override int Calculate(IReadOnlyList<IDice> dice)
|
||||
{
|
||||
return fixedScore;
|
||||
}
|
||||
|
||||
public static FixedScoreCategory Create(string id, int score)
|
||||
{
|
||||
var category = CreateInstance<FixedScoreCategory>();
|
||||
category.SetTestData(id, id);
|
||||
category.fixedScore = score;
|
||||
return category;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10f09d1ab020a9f498748f79ae8c5730
|
||||
Reference in New Issue
Block a user