using PkmnLib.Static.Utils;
namespace PkmnLib.Static;
///
/// A growth rate defines how much experience is required per level.
///
public interface IGrowthRate
{
///
/// The name of the growth rate.
///
public StringKey Name { get; }
///
/// Calculate the level something with this growth rate would have at a certain experience.
///
/// The experience to calculate the level for.
/// The level at the given experience.
LevelInt CalculateLevel(uint experience);
///
/// Calculate the experience something with this growth rate would have at a certain level.
///
/// The level to calculate the experience for.
/// The starting experience at the given level.
uint CalculateExperience(LevelInt level);
}
///
/// An implementation of the growth rate that uses a lookup table for experience.
///
public class LookupGrowthRate : IGrowthRate
{
///
public StringKey Name { get; }
private readonly uint[] _experienceTable;
///
public LookupGrowthRate(StringKey name, IEnumerable 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.");
}
}
///
public LevelInt CalculateLevel(uint experience)
{
for (LevelInt level = 0; level < _experienceTable.Length; level++)
{
if (_experienceTable[level] > experience)
{
return level;
}
}
return (LevelInt)(_experienceTable.Length);
}
///
public uint CalculateExperience(LevelInt level)
{
if (level < 1) level = 1;
return level >= _experienceTable.Length ? _experienceTable[^1] : _experienceTable[level - 1];
}
}