PkmnLib.NET/PkmnLib.Static/GrowthRate.cs

76 lines
2.3 KiB
C#

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];
}
}