using System.Diagnostics.CodeAnalysis; namespace MultiversalDiplomacy.Model; /// /// A timeline of a game. Essentially a wrapper around for tracking the multiversal dimension. /// public struct Timeline { public readonly int number; /// /// Timeline designations for differentiating timelines. Shortenable to the first character. /// 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" }; /// /// Disambiguators used once all primary timeline designations have been used. /// private static readonly string[] secondaryDesignations = new string[] { "", "-prime", "-second", "-third", "-fourth", "-fifth", "-sixth", "-seventh", "-eighth", "-ninth", }; /// /// Short versions of the secondary timeline disambiguators. /// 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; } /// /// The first timeline number. /// public const int FIRST_TIMELINE = 0; /// /// Which primary designation the timeline has. /// private int primaryIndex => number % primaryDesignations.Length; /// /// Which secondary designation the timeline has. /// private int secondaryIndex => number / primaryDesignations.Length; /// /// Returns the timeline's full string representation. /// /// The timeline designation as a string, such as "bravo" or "delta-prime". public override string ToString() => primaryDesignations[primaryIndex] + secondaryDesignations[secondaryIndex]; /// /// Returns a shorter string representation of the timeline. /// /// The timeline's designation as a string, such as "b" or "d'". public string ToShort() => primaryDesignations[primaryIndex][0] + secondaryDesignationsShort[secondaryIndex]; /// /// Returns a value indicating whether this instance is equal to a specified value. /// /// true if obj has the same value as this instance; otherwise, false. public override bool Equals([NotNullWhen(true)] object? obj) => obj is Timeline other ? number.Equals(other.number) : false; /// /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() => number.GetHashCode(); public static int operator -(Timeline first, Timeline second) => Math.Abs(first.number - second.number); }