using PkmnLib.Static.Utils; namespace PkmnLib.Static; /// <summary> /// A growth rate defines how much experience is required per level. /// </summary> public interface IGrowthRate : INamedValue { ///<summary> /// Calculate the level something with this growth rate would have at a certain experience. /// </summary> /// <param name="experience">The experience to calculate the level for.</param> /// <returns>The level at the given experience.</returns> LevelInt CalculateLevel(uint experience); ///<summary> /// Calculate the experience something with this growth rate would have at a certain level. /// </summary> /// <param name="level">The level to calculate the experience for.</param> /// <returns>The starting experience at the given level.</returns> uint CalculateExperience(LevelInt level); } /// <summary> /// An implementation of the growth rate that uses a lookup table for experience. /// </summary> public class LookupGrowthRate : IGrowthRate { /// <inheritdoc /> public StringKey Name { get; } private readonly uint[] _experienceTable; /// <inheritdoc cref="LookupGrowthRate" /> public LookupGrowthRate(StringKey name, IEnumerable<uint> experienceTable) { Name = name; _experienceTable = experienceTable.ToArray(); if (_experienceTable.Length < 1) { throw new ArgumentException("Experience table must have at least one entry."); } if (_experienceTable[0] != 0) { throw new ArgumentException("Experience table must start at 0."); } if (_experienceTable.Length > LevelInt.MaxValue) { throw new ArgumentException($"Experience table may have at most {LevelInt.MaxValue} entries."); } } /// <inheritdoc /> public LevelInt CalculateLevel(uint experience) { for (LevelInt level = 0; level < _experienceTable.Length; level++) { if (_experienceTable[level] > experience) { return level; } } return (LevelInt)(_experienceTable.Length); } /// <inheritdoc /> public uint CalculateExperience(LevelInt level) { if (level < 1) level = 1; return level >= _experienceTable.Length ? _experienceTable[^1] : _experienceTable[level - 1]; } }