我开始使用Everquest TDD Kata(Github Link)进行编码,而我的工作是


  功能:角色能力修饰符修改属性
  
  作为一个角色,我想应用我的能力调整器来提高我的战斗能力,以便我能以极高的偏见战胜敌人
  
  将强度修改器添加到:
  
  
  攻击掷骰和造成的伤害
  暴击时加倍强度修正
  


但我不知道自己的数学是否正确。使用NUnit的TestCaseSource,我进行以下测试

[TestFixture]
public class CharacterAbilityTests
{
    [TestCaseSource("StrengthAbilityTestCases", Category = "Character Strength Tests")]
    public int StrengthAbiltyAddsModifierToAttackRollAndDamage(Character hero, int hitroll)
    {
        var enemy = new Character();
        Assert.That(hero.Attack(enemy, hitroll), Is.True);

        return enemy.HitPoints;
    }

    private static IEnumerable<TestCaseData> StrengthAbilityTestCases
    {
        get
        {
            yield return My.Hero.WithStrength(12).RollsHitOf(9).LeavesEnemyWithHitPoints(3);
            yield return My.Hero.WithStrength(14).RollsHitOf(8).LeavesEnemyWithHitPoints(2);
            yield return My.Hero.WithStrength(16).RollsHitOf(7).LeavesEnemyWithHitPoints(1);
            yield return My.Hero.WithStrength(19).RollsHitOf(6).LeavesEnemyWithHitPoints(0);
            yield return My.Hero.WithStrength(20).RollsHitOf(5).LeavesEnemyWithHitPoints(-1);

            yield return My.Hero.WithStrength(12).RollsHitOf(20).LeavesEnemyWithHitPoints(2);
            yield return My.Hero.WithStrength(14).RollsHitOf(20).LeavesEnemyWithHitPoints(0);
            yield return My.Hero.WithStrength(16).RollsHitOf(20).LeavesEnemyWithHitPoints(-2);
            yield return My.Hero.WithStrength(19).RollsHitOf(20).LeavesEnemyWithHitPoints(-4);
            yield return My.Hero.WithStrength(20).RollsHitOf(20).LeavesEnemyWithHitPoints(-6);
        }
    }
    private class My
    {
        private Character hero;
        private int hitRoll;

        public static My Hero { get { return new My(); } }
        private My() { hero = new Character(); }

        public My WithStrength(int strength){hero.Strength = strength;return this;}
        public My RollsHitOf(int hitRoll) { this.hitRoll = hitRoll; return this; }

        public TestCaseData LeavesEnemyWithHitPoints(int expectedHitPoints)
        {
            var testCaseData = new TestCaseData(hero, hitRoll)
            {
                HasExpectedResult = true,
                ExpectedResult = expectedHitPoints,
                TestName = $"Hero with Stength of {hero.Strength} rolling a {hitRoll} Should leave enemy with {expectedHitPoints} Hit points"
            };

            return testCaseData;
        }
    }
}


而且我所有处理关键命中的测试都失败了(最后5个测试)问题是我不确定我的数学是否正确。这是我的攻击方法:(请注意,我之前的所有测试当前都通过了)

public class Character
{
    public string Name { get; set; }
    public Alignment Alignment { get; set; }
    public int ArmorClass { get; private set; }
    public int HitPoints { get; private set; }
    public bool IsDead { get { return HitPoints <= 0; } }

    public Ability Strength { get; set; }
    public Ability Dexterity { get; set; }
    public Ability Constitution { get; set; }
    public Ability Wisdom { get; set; }
    public Ability Intelligence { get; set; }
    public Ability Charisma { get; set; }

    public Character()
    {
        ArmorClass = 10;
        HitPoints = 5;
        Strength = 10;
        Dexterity = 10;
        Constitution = 10;
        Wisdom = 10;
        Intelligence = 10;
        Charisma = 10;
    }

    public bool Attack(Character enemy, int hitRoll)
    {
        var damage = 0;
        var modifier = IsCritHit(hitRoll) ? Strength.Modifier * 2 : Strength.Modifier;
        var isEnemyHit = IsCritHit(hitRoll) || (enemy.ArmorClass <= (hitRoll + modifier));

        if (!isEnemyHit) return false;

        damage = 1 + modifier;
        if (IsCritHit(hitRoll)) damage *= 2;
        enemy.TakeDamage(damage);

        return true;
    }

    private static bool IsCritHit(int hitRoll)
    {
        return hitRoll == 20;
    }

    public void TakeDamage(int damage)
    {
        HitPoints-= damage;
    }
}

public class Ability
{
    public int Score { get; private set; }
    public int Modifier { get; private set; }

    private Ability(int score)
    {
        Score = score;
        Modifier = (int)(Math.Floor((Score - 10) / 2.0));
    }

    public override string ToString()
    {
        return $"{Score} [{Modifier}]";
    }
    public static implicit operator int(Ability ability)
    {
        return ability.Score;
    }

    public static implicit operator Ability(int score)
    {
        return new Ability(score);
    }
}


编辑

我忘记了AC和HP的幻数分别是10和5。它们来自于Kata的规格。

编辑2.0

这是我5个失败的测试中的第一个的输出

Test Name:  Hero with Stength of 12 [1] rolling a 20 Should leave enemy with 2 Hit points
Test FullName:  EmptyProject.Tests.CharacterAbilityTests.Hero with Stength of 12 [1] rolling a 20 Should leave enemy with 2 Hit points
Test Source:    D:\Users\Robert\Source\Repos\EverCraft-Kata\dotNet\src\EmptyProject.Tests\CharacterAbilityTests.cs : line 14
Test Outcome:   Failed
Test Duration:  0:00:00.012

Result StackTrace:
at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
at NUnit.Framework.Internal.Commands.TestActionCommand.Execute(TestExecutionContext context)
Result Message:
Expected: 2
  But was:  -1


希望最终编辑

我想问一下是(baseDamage + strengthModifier)* 2,还是(baseDamage * 2)+ strengthModifier

最佳答案

您的.LeavesEnemyWithHitPoints(2)是错误的。应该是-1。

本节代码:

var damage = 0;
var modifier = IsCritHit(hitRoll) ? Strength.Modifier * 2 : Strength.Modifier;
var isEnemyHit = IsCritHit(hitRoll) || (enemy.ArmorClass <= (hitRoll + modifier));

if (!isEnemyHit) return false;

damage = 1 + modifier;
if (IsCritHit(hitRoll)) damage *= 2;
    enemy.TakeDamage(damage);


Strength.Modifier为1时,您的modifier计算在重击时产生2。这意味着damage = 1 + modifier为3。因为您已掷出暴击,伤害加倍,因此您的总damage =6。如果敌人的总HP为5,而您对他的打击为6,则他应具有-1 HP。

我不知道这是否是正确的DnD计算(不记得了)

10-07 22:24