也许从某个事件处理程序中,您想决定要施放什么咒语。也许你可以从这个施法者开始:
public class Caster
{
    private readonly ICastable[] _spells;
    private int _canCastAt;
    public Caster(ICastable[] spells)
    {
        _spells = spells;
        _canCastAt = -1;
    }
    public string GetNextSpellToCast(int currentTime)
    {
        if (currentTime < _canCastAt)
            return null;
        for (int i = 0; i < _spells.Length; i++)
        {
            int durationOfCast = _spells[i].AttemptCast(currentTime);
            if (durationOfCast > 0)
            {
                _canCastAt = currentTime + durationOfCast;
                return _spells[i].GetName();
            }
        }
        return null;
    }
}
施法者会施法:
public interface ICastable
{
    string GetName();
    int AttemptCast(int msCurrentTime);
}
你描述了一种特殊的咒语:
public class ChanneledSpell : ICastable
{
    private readonly string _name;
    private readonly int _castDuration;
    private readonly int _castCooldown;
    private int _lastCast;
    public ChanneledSpell(string name, int castDuration, int castCooldown)
    {
        Debug.Assert(castDuration < castCooldown);  // a reasonable assumption the tests makes
        _name = name;
        _castDuration = castDuration;
        _castCooldown = castCooldown;
        _lastCast = -_castCooldown;
    }
    public string GetName()
    {
        return _name;
    }
    public int AttemptCast(int msCurrentTime)
    {
        if (msCurrentTime > _lastCast + _castCooldown)
        {
            _lastCast = msCurrentTime;
            return _castDuration;
        }
        return 0;
    }
}
我看到这被标记为 C++,这个答案是 C#,虽然我只使用了 C++ 中可用的语言结构,所以它应该是一个简单的翻译。我不能这么容易翻译的是一些测试,
[TestFixture]
public class SpellTest
{
    [Test]
    public void TestCanCastOnStartup()
    {
        var sut = new ChanneledSpell(Some.String(), Some.PositiveNonzeroInteger(), Some.PositiveNonzeroInteger());
        int result = sut.AttemptCast(Some.PositiveNonzeroInteger());
        Assert.IsTrue(CastWasMade(result));
    }
    [Test]
    public void TestCantCastUntilCooldown()
    {
        int firstCast = Some.PositiveNonzeroInteger();
        int duration = Some.PositiveNonzeroInteger();
        int cooldown = duration + Some.PositiveNonzeroInteger();  // assuming spell duration is less then cooldown
        var sut = new ChanneledSpell(Some.String(), duration, cooldown);
        int ignored = sut.AttemptCast(firstCast);
        int secondCastAttempt = sut.AttemptCast(firstCast + cooldown - 1);
        int thirdCastAttempt = sut.AttemptCast(firstCast + cooldown + 1);
        Assert.IsFalse(CastWasMade(secondCastAttempt));
        Assert.IsTrue(CastWasMade(thirdCastAttempt));
    }
    [Test]
    public void TestReportsTimeOnCast()
    {
        int duration = Some.PositiveNonzeroInteger();
        int firstCastTime = Some.PositiveNonzeroInteger();
        var sut = new ChanneledSpell(Some.String(), duration, Some.PositiveNonzeroInteger());
        int firstCastAttempt = sut.AttemptCast(firstCastTime);
        Assert.AreEqual(duration, firstCastAttempt);
    }
    private bool CastWasMade(int result)
    {
        return result > 0;
    }
}