86 lines
3.1 KiB
C#
86 lines
3.1 KiB
C#
namespace PkmnLib.Dynamic.Models.Choices;
|
|
|
|
/// <summary>
|
|
/// Comparer for turnchoices, to determine the order in which they should be executed.
|
|
/// </summary>
|
|
public class TurnChoiceComparer : IComparer<ITurnChoice>
|
|
{
|
|
/// <inheritdoc cref="TurnChoiceComparer"/>
|
|
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;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public int Compare(ITurnChoice? x, ITurnChoice? y) => (int) CompareImpl(x, y);
|
|
} |