diff --git a/documentation/DocumentationTest.SkillPointDocumentation.approved.md b/documentation/DocumentationTest.SkillPointDocumentation.approved.md new file mode 100644 index 0000000..c1e59c3 --- /dev/null +++ b/documentation/DocumentationTest.SkillPointDocumentation.approved.md @@ -0,0 +1,350 @@ +# Skill Point (CP) Table +## Class Adventurer +- Job level 1 - CP: 2 +- Job level 2 - CP: 4 +- Job level 3 - CP: 6 +- Job level 4 - CP: 8 +- Job level 5 - CP: 10 +- Job level 6 - CP: 12 +- Job level 7 - CP: 14 +- Job level 8 - CP: 16 +- Job level 9 - CP: 18 +- Job level 10 - CP: 20 +- Job level 11 - CP: 22 +- Job level 12 - CP: 24 +- Job level 13 - CP: 26 +- Job level 14 - CP: 28 +- Job level 15 - CP: 30 +- Job level 16 - CP: 32 +- Job level 17 - CP: 34 +- Job level 18 - CP: 36 +- Job level 19 - CP: 38 +- Job level 20 - CP: 40 + +## Class Swordsman +- Job level 1 - CP: 42 +- Job level 2 - CP: 44 +- Job level 3 - CP: 46 +- Job level 4 - CP: 48 +- Job level 5 - CP: 50 +- Job level 6 - CP: 52 +- Job level 7 - CP: 54 +- Job level 8 - CP: 56 +- Job level 9 - CP: 58 +- Job level 10 - CP: 60 +- Job level 11 - CP: 62 +- Job level 12 - CP: 64 +- Job level 13 - CP: 66 +- Job level 14 - CP: 68 +- Job level 15 - CP: 70 +- Job level 16 - CP: 72 +- Job level 17 - CP: 74 +- Job level 18 - CP: 76 +- Job level 19 - CP: 78 +- Job level 20 - CP: 80 +- Job level 21 - CP: 82 +- Job level 22 - CP: 84 +- Job level 23 - CP: 86 +- Job level 24 - CP: 88 +- Job level 25 - CP: 90 +- Job level 26 - CP: 92 +- Job level 27 - CP: 94 +- Job level 28 - CP: 96 +- Job level 29 - CP: 98 +- Job level 30 - CP: 100 +- Job level 31 - CP: 102 +- Job level 32 - CP: 104 +- Job level 33 - CP: 106 +- Job level 34 - CP: 108 +- Job level 35 - CP: 110 +- Job level 36 - CP: 112 +- Job level 37 - CP: 114 +- Job level 38 - CP: 116 +- Job level 39 - CP: 118 +- Job level 40 - CP: 120 +- Job level 41 - CP: 122 +- Job level 42 - CP: 124 +- Job level 43 - CP: 126 +- Job level 44 - CP: 128 +- Job level 45 - CP: 130 +- Job level 46 - CP: 132 +- Job level 47 - CP: 134 +- Job level 48 - CP: 136 +- Job level 49 - CP: 138 +- Job level 50 - CP: 140 +- Job level 51 - CP: 142 +- Job level 52 - CP: 144 +- Job level 53 - CP: 146 +- Job level 54 - CP: 148 +- Job level 55 - CP: 150 +- Job level 56 - CP: 152 +- Job level 57 - CP: 154 +- Job level 58 - CP: 156 +- Job level 59 - CP: 158 +- Job level 60 - CP: 160 +- Job level 61 - CP: 162 +- Job level 62 - CP: 164 +- Job level 63 - CP: 166 +- Job level 64 - CP: 168 +- Job level 65 - CP: 170 +- Job level 66 - CP: 172 +- Job level 67 - CP: 174 +- Job level 68 - CP: 176 +- Job level 69 - CP: 178 +- Job level 70 - CP: 180 +- Job level 71 - CP: 182 +- Job level 72 - CP: 184 +- Job level 73 - CP: 186 +- Job level 74 - CP: 188 +- Job level 75 - CP: 190 +- Job level 76 - CP: 192 +- Job level 77 - CP: 194 +- Job level 78 - CP: 196 +- Job level 79 - CP: 198 +- Job level 80 - CP: 200 + +## Class Archer +- Job level 1 - CP: 42 +- Job level 2 - CP: 44 +- Job level 3 - CP: 46 +- Job level 4 - CP: 48 +- Job level 5 - CP: 50 +- Job level 6 - CP: 52 +- Job level 7 - CP: 54 +- Job level 8 - CP: 56 +- Job level 9 - CP: 58 +- Job level 10 - CP: 60 +- Job level 11 - CP: 62 +- Job level 12 - CP: 64 +- Job level 13 - CP: 66 +- Job level 14 - CP: 68 +- Job level 15 - CP: 70 +- Job level 16 - CP: 72 +- Job level 17 - CP: 74 +- Job level 18 - CP: 76 +- Job level 19 - CP: 78 +- Job level 20 - CP: 80 +- Job level 21 - CP: 82 +- Job level 22 - CP: 84 +- Job level 23 - CP: 86 +- Job level 24 - CP: 88 +- Job level 25 - CP: 90 +- Job level 26 - CP: 92 +- Job level 27 - CP: 94 +- Job level 28 - CP: 96 +- Job level 29 - CP: 98 +- Job level 30 - CP: 100 +- Job level 31 - CP: 102 +- Job level 32 - CP: 104 +- Job level 33 - CP: 106 +- Job level 34 - CP: 108 +- Job level 35 - CP: 110 +- Job level 36 - CP: 112 +- Job level 37 - CP: 114 +- Job level 38 - CP: 116 +- Job level 39 - CP: 118 +- Job level 40 - CP: 120 +- Job level 41 - CP: 122 +- Job level 42 - CP: 124 +- Job level 43 - CP: 126 +- Job level 44 - CP: 128 +- Job level 45 - CP: 130 +- Job level 46 - CP: 132 +- Job level 47 - CP: 134 +- Job level 48 - CP: 136 +- Job level 49 - CP: 138 +- Job level 50 - CP: 140 +- Job level 51 - CP: 142 +- Job level 52 - CP: 144 +- Job level 53 - CP: 146 +- Job level 54 - CP: 148 +- Job level 55 - CP: 150 +- Job level 56 - CP: 152 +- Job level 57 - CP: 154 +- Job level 58 - CP: 156 +- Job level 59 - CP: 158 +- Job level 60 - CP: 160 +- Job level 61 - CP: 162 +- Job level 62 - CP: 164 +- Job level 63 - CP: 166 +- Job level 64 - CP: 168 +- Job level 65 - CP: 170 +- Job level 66 - CP: 172 +- Job level 67 - CP: 174 +- Job level 68 - CP: 176 +- Job level 69 - CP: 178 +- Job level 70 - CP: 180 +- Job level 71 - CP: 182 +- Job level 72 - CP: 184 +- Job level 73 - CP: 186 +- Job level 74 - CP: 188 +- Job level 75 - CP: 190 +- Job level 76 - CP: 192 +- Job level 77 - CP: 194 +- Job level 78 - CP: 196 +- Job level 79 - CP: 198 +- Job level 80 - CP: 200 + +## Class Mage +- Job level 1 - CP: 42 +- Job level 2 - CP: 44 +- Job level 3 - CP: 46 +- Job level 4 - CP: 48 +- Job level 5 - CP: 50 +- Job level 6 - CP: 52 +- Job level 7 - CP: 54 +- Job level 8 - CP: 56 +- Job level 9 - CP: 58 +- Job level 10 - CP: 60 +- Job level 11 - CP: 62 +- Job level 12 - CP: 64 +- Job level 13 - CP: 66 +- Job level 14 - CP: 68 +- Job level 15 - CP: 70 +- Job level 16 - CP: 72 +- Job level 17 - CP: 74 +- Job level 18 - CP: 76 +- Job level 19 - CP: 78 +- Job level 20 - CP: 80 +- Job level 21 - CP: 82 +- Job level 22 - CP: 84 +- Job level 23 - CP: 86 +- Job level 24 - CP: 88 +- Job level 25 - CP: 90 +- Job level 26 - CP: 92 +- Job level 27 - CP: 94 +- Job level 28 - CP: 96 +- Job level 29 - CP: 98 +- Job level 30 - CP: 100 +- Job level 31 - CP: 102 +- Job level 32 - CP: 104 +- Job level 33 - CP: 106 +- Job level 34 - CP: 108 +- Job level 35 - CP: 110 +- Job level 36 - CP: 112 +- Job level 37 - CP: 114 +- Job level 38 - CP: 116 +- Job level 39 - CP: 118 +- Job level 40 - CP: 120 +- Job level 41 - CP: 122 +- Job level 42 - CP: 124 +- Job level 43 - CP: 126 +- Job level 44 - CP: 128 +- Job level 45 - CP: 130 +- Job level 46 - CP: 132 +- Job level 47 - CP: 134 +- Job level 48 - CP: 136 +- Job level 49 - CP: 138 +- Job level 50 - CP: 140 +- Job level 51 - CP: 142 +- Job level 52 - CP: 144 +- Job level 53 - CP: 146 +- Job level 54 - CP: 148 +- Job level 55 - CP: 150 +- Job level 56 - CP: 152 +- Job level 57 - CP: 154 +- Job level 58 - CP: 156 +- Job level 59 - CP: 158 +- Job level 60 - CP: 160 +- Job level 61 - CP: 162 +- Job level 62 - CP: 164 +- Job level 63 - CP: 166 +- Job level 64 - CP: 168 +- Job level 65 - CP: 170 +- Job level 66 - CP: 172 +- Job level 67 - CP: 174 +- Job level 68 - CP: 176 +- Job level 69 - CP: 178 +- Job level 70 - CP: 180 +- Job level 71 - CP: 182 +- Job level 72 - CP: 184 +- Job level 73 - CP: 186 +- Job level 74 - CP: 188 +- Job level 75 - CP: 190 +- Job level 76 - CP: 192 +- Job level 77 - CP: 194 +- Job level 78 - CP: 196 +- Job level 79 - CP: 198 +- Job level 80 - CP: 200 + +## Class MartialArtist +- Job level 1 - CP: 42 +- Job level 2 - CP: 44 +- Job level 3 - CP: 46 +- Job level 4 - CP: 48 +- Job level 5 - CP: 50 +- Job level 6 - CP: 52 +- Job level 7 - CP: 54 +- Job level 8 - CP: 56 +- Job level 9 - CP: 58 +- Job level 10 - CP: 60 +- Job level 11 - CP: 62 +- Job level 12 - CP: 64 +- Job level 13 - CP: 66 +- Job level 14 - CP: 68 +- Job level 15 - CP: 70 +- Job level 16 - CP: 72 +- Job level 17 - CP: 74 +- Job level 18 - CP: 76 +- Job level 19 - CP: 78 +- Job level 20 - CP: 80 +- Job level 21 - CP: 82 +- Job level 22 - CP: 84 +- Job level 23 - CP: 86 +- Job level 24 - CP: 88 +- Job level 25 - CP: 90 +- Job level 26 - CP: 92 +- Job level 27 - CP: 94 +- Job level 28 - CP: 96 +- Job level 29 - CP: 98 +- Job level 30 - CP: 100 +- Job level 31 - CP: 102 +- Job level 32 - CP: 104 +- Job level 33 - CP: 106 +- Job level 34 - CP: 108 +- Job level 35 - CP: 110 +- Job level 36 - CP: 112 +- Job level 37 - CP: 114 +- Job level 38 - CP: 116 +- Job level 39 - CP: 118 +- Job level 40 - CP: 120 +- Job level 41 - CP: 122 +- Job level 42 - CP: 124 +- Job level 43 - CP: 126 +- Job level 44 - CP: 128 +- Job level 45 - CP: 130 +- Job level 46 - CP: 132 +- Job level 47 - CP: 134 +- Job level 48 - CP: 136 +- Job level 49 - CP: 138 +- Job level 50 - CP: 140 +- Job level 51 - CP: 142 +- Job level 52 - CP: 144 +- Job level 53 - CP: 146 +- Job level 54 - CP: 148 +- Job level 55 - CP: 150 +- Job level 56 - CP: 152 +- Job level 57 - CP: 154 +- Job level 58 - CP: 156 +- Job level 59 - CP: 158 +- Job level 60 - CP: 160 +- Job level 61 - CP: 162 +- Job level 62 - CP: 164 +- Job level 63 - CP: 166 +- Job level 64 - CP: 168 +- Job level 65 - CP: 170 +- Job level 66 - CP: 172 +- Job level 67 - CP: 174 +- Job level 68 - CP: 176 +- Job level 69 - CP: 178 +- Job level 70 - CP: 180 +- Job level 71 - CP: 182 +- Job level 72 - CP: 184 +- Job level 73 - CP: 186 +- Job level 74 - CP: 188 +- Job level 75 - CP: 190 +- Job level 76 - CP: 192 +- Job level 77 - CP: 194 +- Job level 78 - CP: 196 +- Job level 79 - CP: 198 +- Job level 80 - CP: 200 diff --git a/src/NosCore.Algorithm/SkillPointService/ISkillPointService.cs b/src/NosCore.Algorithm/SkillPointService/ISkillPointService.cs new file mode 100644 index 0000000..ae8cbfc --- /dev/null +++ b/src/NosCore.Algorithm/SkillPointService/ISkillPointService.cs @@ -0,0 +1,24 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// ----------------------------------- + +using NosCore.Shared.Enumerations; + +namespace NosCore.Algorithm.SkillPointService +{ + /// + /// Service for the skill points (CP) a character spends on class skills + /// + public interface ISkillPointService + { + /// + /// Gets the CP a character has before any skill is learned + /// + /// The character's class + /// The character's job level + /// The CP pool + int GetSkillPoints(CharacterClassType @class, byte jobLevel); + } +} diff --git a/src/NosCore.Algorithm/SkillPointService/SkillPointService.cs b/src/NosCore.Algorithm/SkillPointService/SkillPointService.cs new file mode 100644 index 0000000..5a2cb21 --- /dev/null +++ b/src/NosCore.Algorithm/SkillPointService/SkillPointService.cs @@ -0,0 +1,27 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// ----------------------------------- + +using NosCore.Shared.Enumerations; + +namespace NosCore.Algorithm.SkillPointService +{ + /// + /// Provides the CP pool: two per job level, plus forty once the character has a class + /// + public class SkillPointService : ISkillPointService + { + private const int ClassBonus = 40; + private const int PerJobLevel = 2; + + // Login traces of job level 80 characters show 200 CP once their active skills are + // paid for, which fits this curve at its cap. No trace below the cap has been checked. + /// + public int GetSkillPoints(CharacterClassType @class, byte jobLevel) + { + return (@class == CharacterClassType.Adventurer ? 0 : ClassBonus) + PerJobLevel * jobLevel; + } + } +} diff --git a/test/NosCore.Algorithm.Tests/DocumentationTest.cs b/test/NosCore.Algorithm.Tests/DocumentationTest.cs index 639bcde..19ccd2f 100644 --- a/test/NosCore.Algorithm.Tests/DocumentationTest.cs +++ b/test/NosCore.Algorithm.Tests/DocumentationTest.cs @@ -290,6 +290,26 @@ public void JobExperienceDocumentation() Approvals.Verify(WriterFactory.CreateTextWriter(resultBuilder.ToString(), "md")); } + [TestMethod] + public void SkillPointDocumentation() + { + var skillPointService = new SkillPointService.SkillPointService(); + + var resultBuilder = new StringBuilder("# Skill Point (CP) Table"); + foreach (var @class in Enum.GetValues(typeof(CharacterClassType)).Cast()) + { + resultBuilder.AppendLine(); + resultBuilder.AppendLine($"## Class {@class}"); + for (byte level = 1; level < (@class == CharacterClassType.Adventurer ? 21 : 81); level++) + { + resultBuilder.AppendLine( + $"- Job level {level,2} - CP: {skillPointService.GetSkillPoints(@class, level)}"); + } + } + + Approvals.Verify(WriterFactory.CreateTextWriter(resultBuilder.ToString(), "md")); + } + [TestMethod] public void HitDodgeDocumentation() {