139 lines
3.8 KiB
C#
139 lines
3.8 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace MultiversalDiplomacy.Model;
|
|
|
|
/// <summary>
|
|
/// A timeline of a game. Essentially a wrapper around <see cref="int"/> for tracking the multiversal dimension.
|
|
/// </summary>
|
|
public struct Timeline
|
|
{
|
|
public readonly int number;
|
|
|
|
/// <summary>
|
|
/// Timeline designations for differentiating timelines. Shortenable to the first character.
|
|
/// </summary>
|
|
private static readonly string[] primaryDesignations = new string[]
|
|
{
|
|
"alfa",
|
|
"bravo",
|
|
"charlie",
|
|
"delta",
|
|
"echo",
|
|
"foxtrot",
|
|
"golf",
|
|
"hotel",
|
|
"india",
|
|
"juliett",
|
|
"kilo",
|
|
"lima",
|
|
"mike",
|
|
"november",
|
|
"oscar",
|
|
"papa",
|
|
"quebec",
|
|
"romeo",
|
|
"sierra",
|
|
"tango",
|
|
"uniform",
|
|
"victor",
|
|
"whiskey",
|
|
"xray",
|
|
"yankee",
|
|
"zulu"
|
|
};
|
|
|
|
/// <summary>
|
|
/// Disambiguators used once all primary timeline designations have been used.
|
|
/// </summary>
|
|
private static readonly string[] secondaryDesignations = new string[]
|
|
{
|
|
"",
|
|
"-prime",
|
|
"-second",
|
|
"-third",
|
|
"-fourth",
|
|
"-fifth",
|
|
"-sixth",
|
|
"-seventh",
|
|
"-eighth",
|
|
"-ninth",
|
|
};
|
|
|
|
/// <summary>
|
|
/// Short versions of the secondary timeline disambiguators.
|
|
/// </summary>
|
|
private static readonly string[] secondaryDesignationsShort = new string[]
|
|
{
|
|
"",
|
|
"'",
|
|
"\"",
|
|
"\x2073",
|
|
"\x2074",
|
|
"\x2075",
|
|
"\x2076",
|
|
"\x2077",
|
|
"\x2078",
|
|
"\x2079",
|
|
};
|
|
|
|
public Timeline(int number)
|
|
{
|
|
if (number < FIRST_TIMELINE)
|
|
{
|
|
throw new ArgumentException($"Invalid timeline number: {number}", nameof(number));
|
|
}
|
|
if (number >= primaryDesignations.Length * secondaryDesignations.Length)
|
|
{
|
|
throw new ArgumentException($"Timeline number too high: {number}", nameof(number));
|
|
}
|
|
this.number = number;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The first timeline number.
|
|
/// </summary>
|
|
public const int FIRST_TIMELINE = 0;
|
|
|
|
/// <summary>
|
|
/// Which primary designation the timeline has.
|
|
/// </summary>
|
|
private int primaryIndex => number % primaryDesignations.Length;
|
|
|
|
/// <summary>
|
|
/// Which secondary designation the timeline has.
|
|
/// </summary>
|
|
private int secondaryIndex => number / primaryDesignations.Length;
|
|
|
|
/// <summary>
|
|
/// Returns the timeline's full string representation.
|
|
/// </summary>
|
|
/// <returns>The timeline designation as a string, such as "bravo" or "delta-prime".</returns>
|
|
public override string ToString()
|
|
=> primaryDesignations[primaryIndex] + secondaryDesignations[secondaryIndex];
|
|
|
|
/// <summary>
|
|
/// Returns a shorter string representation of the timeline.
|
|
/// </summary>
|
|
/// <returns>The timeline's designation as a string, such as "b" or "d'".</returns>
|
|
public string ToShort()
|
|
=> primaryDesignations[primaryIndex][0] + secondaryDesignationsShort[secondaryIndex];
|
|
|
|
/// <summary>
|
|
/// Returns a value indicating whether this instance is equal to a specified <see cref="Timeline"/> value.
|
|
/// </summary>
|
|
/// <returns>true if obj has the same value as this instance; otherwise, false.</returns>
|
|
public override bool Equals([NotNullWhen(true)] object? obj)
|
|
=> obj is Timeline other
|
|
? number.Equals(other.number)
|
|
: false;
|
|
|
|
/// <summary>
|
|
/// Returns the hash code for this instance.
|
|
/// </summary>
|
|
/// <returns>A 32-bit signed integer hash code.</returns>
|
|
public override int GetHashCode()
|
|
=> number.GetHashCode();
|
|
|
|
public static int operator -(Timeline first, Timeline second)
|
|
=> Math.Abs(first.number - second.number);
|
|
} |