namespace PkmnLib.Dynamic.Models.Choices; /// /// Comparer for turnchoices, to determine the order in which they should be executed. /// public class TurnChoiceComparer : IComparer { /// public static TurnChoiceComparer Instance { get; } = new(); private enum CompareValues { XEqualsY = 0, XLessThanY = -1, XGreaterThanY = 1 } private static CompareValues CompareForSameType(ITurnChoice x, ITurnChoice y) { // Higher speed goes first var speedComparison = x.Speed.CompareTo(y.Speed); if (speedComparison != 0) return (CompareValues)speedComparison; // If speed is equal, we use the random values we've given to each choice to tiebreak. // This is to ensure that the order of choices is deterministic. return (CompareValues)x.RandomValue.CompareTo(y.RandomValue); } private static CompareValues CompareImpl(ITurnChoice? x, ITurnChoice? y) { // Deal with possible null values switch (x) { case null when y is null: return CompareValues.XEqualsY; case null: return CompareValues.XLessThanY; } if (y is null) return CompareValues.XGreaterThanY; switch (x) { case IMoveChoice moveX: // Move choices go first if (y is IMoveChoice moveY) { // Higher priority goes first var priorityComparison = moveX.Priority.CompareTo(moveY.Priority); if (priorityComparison != 0) return (CompareValues)priorityComparison; return CompareForSameType(moveX, moveY); } return CompareValues.XGreaterThanY; case IItemChoice itemX: // Item choices go second return y switch { IMoveChoice => CompareValues.XLessThanY, IItemChoice itemY => CompareForSameType(itemX, itemY), _ => CompareValues.XGreaterThanY }; case ISwitchChoice switchX: // Switch choices go third return y switch { IMoveChoice or IItemChoice => CompareValues.XLessThanY, ISwitchChoice switchY => CompareForSameType(switchX, switchY), _ => CompareValues.XGreaterThanY }; case IPassChoice passX: // Pass choices go last return y switch { IMoveChoice or IItemChoice or ISwitchChoice => CompareValues.XLessThanY, IPassChoice passY => CompareForSameType(passX, passY), _ => CompareValues.XGreaterThanY }; } return CompareValues.XLessThanY; } /// public int Compare(ITurnChoice? x, ITurnChoice? y) => (int) CompareImpl(x, y); }