2024-08-12 14:33:17 +00:00
|
|
|
namespace MultiversalDiplomacy.Model;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// A shared counter for handing out new timeline designations.
|
|
|
|
/// </summary>
|
2024-08-13 22:24:40 +00:00
|
|
|
public class TimelineFactory
|
2024-08-12 14:33:17 +00:00
|
|
|
{
|
|
|
|
private static readonly char[] Letters = [
|
|
|
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
|
|
|
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
|
|
|
'u', 'v', 'w', 'x', 'y', 'z',
|
|
|
|
];
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Convert a string timeline identifier to its serial number.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="timeline">Timeline identifier.</param>
|
|
|
|
/// <returns>Integer.</returns>
|
|
|
|
public static int StringToInt(string timeline)
|
|
|
|
{
|
|
|
|
int result = Array.IndexOf(Letters, timeline[0]);
|
|
|
|
for (int i = 1; i < timeline.Length; i++) {
|
|
|
|
// The result is incremented by one because timeline designations are not a true base26 system.
|
|
|
|
// The "ones digit" maps a-z 0-25, but the "tens digit" maps a to 1, so "10" (26) is "aa" and not "a0"
|
|
|
|
result = (result + 1) * 26;
|
|
|
|
result += Array.IndexOf(Letters, timeline[i]);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Convert a timeline serial number to its string identifier.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="designation">Integer.</param>
|
|
|
|
/// <returns>Timeline identifier.</returns>
|
|
|
|
public static string IntToString(int designation) {
|
|
|
|
static int downshift(int i ) => (i - (i % 26)) / 26;
|
|
|
|
IEnumerable<char> result = [Letters[designation % 26]];
|
|
|
|
for (int remainder = downshift(designation); remainder > 0; remainder = downshift(remainder) - 1) {
|
|
|
|
// We subtract 1 after downshifting for the same reason we add 1 above after upshifting.
|
|
|
|
//
|
|
|
|
result = result.Prepend(Letters[(remainder % 26 + 25) % 26]);
|
|
|
|
}
|
|
|
|
return new string(result.ToArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
private int nextTimeline = 0;
|
|
|
|
|
|
|
|
public string NextTimeline() => IntToString(nextTimeline++);
|
|
|
|
}
|