Add convoy parsing regex
This commit is contained in:
parent
ddf951c17e
commit
46b18eda33
|
@ -28,12 +28,14 @@ public class OrderParser(World world)
|
||||||
|
|
||||||
public const string HoldVerb = "(h|hold|holds)";
|
public const string HoldVerb = "(h|hold|holds)";
|
||||||
|
|
||||||
public const string MoveVerb = "(-|(?:->)|(?:=>)|(?:attack(?:s)?)|(?:move(?:s)?(?: to)?))";
|
public const string MoveVerb = "(-|(?:->)|(?:=>)|(?:to)|(?:attack(?:s)?)|(?:move(?:s)?(?: to)?))";
|
||||||
|
|
||||||
public const string SupportVerb = "(s|support|supports)";
|
public const string SupportVerb = "(s|support|supports)";
|
||||||
|
|
||||||
public const string ViaConvoy = "(convoy|via convoy|by convoy)";
|
public const string ViaConvoy = "(convoy|via convoy|by convoy)";
|
||||||
|
|
||||||
|
public const string ConvoyVerb = "(c|convoy|convoys)";
|
||||||
|
|
||||||
public Regex UnitDeclaration = new(
|
public Regex UnitDeclaration = new(
|
||||||
$"^{world.Map.PowerRegex} {Type} {world.Map.ProvinceRegex}(?:{SlashLocation}|{ParenLocation})?$",
|
$"^{world.Map.PowerRegex} {Type} {world.Map.ProvinceRegex}(?:{SlashLocation}|{ParenLocation})?$",
|
||||||
RegexOptions.IgnoreCase);
|
RegexOptions.IgnoreCase);
|
||||||
|
@ -183,6 +185,51 @@ public class OrderParser(World world)
|
||||||
: match.Groups[18].Value,
|
: match.Groups[18].Value,
|
||||||
match.Groups[19].Value);
|
match.Groups[19].Value);
|
||||||
|
|
||||||
|
public Regex Convoy => new(
|
||||||
|
$"{UnitSpec} {ConvoyVerb} {UnitSpec} {MoveVerb} {FullLocation}$",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
public static (
|
||||||
|
string type,
|
||||||
|
string timeline,
|
||||||
|
string province,
|
||||||
|
string location,
|
||||||
|
string turn,
|
||||||
|
string convoyVerb,
|
||||||
|
string targetType,
|
||||||
|
string targetTimeline,
|
||||||
|
string targetProvince,
|
||||||
|
string targetLocation,
|
||||||
|
string targetTurn,
|
||||||
|
string moveVerb,
|
||||||
|
string destTimeline,
|
||||||
|
string destProvince,
|
||||||
|
string destLocation,
|
||||||
|
string destTurn)
|
||||||
|
ParseConvoy(Match match) => (
|
||||||
|
match.Groups[1].Value,
|
||||||
|
match.Groups[2].Value,
|
||||||
|
match.Groups[3].Value,
|
||||||
|
match.Groups[4].Length > 0
|
||||||
|
? match.Groups[4].Value
|
||||||
|
: match.Groups[5].Value,
|
||||||
|
match.Groups[6].Value,
|
||||||
|
match.Groups[7].Value,
|
||||||
|
match.Groups[8].Value,
|
||||||
|
match.Groups[9].Value,
|
||||||
|
match.Groups[10].Value,
|
||||||
|
match.Groups[11].Length > 0
|
||||||
|
? match.Groups[11].Value
|
||||||
|
: match.Groups[12].Value,
|
||||||
|
match.Groups[13].Value,
|
||||||
|
match.Groups[14].Value,
|
||||||
|
match.Groups[15].Value,
|
||||||
|
match.Groups[16].Value,
|
||||||
|
match.Groups[17].Length > 0
|
||||||
|
? match.Groups[17].Value
|
||||||
|
: match.Groups[18].Value,
|
||||||
|
match.Groups[19].Value);
|
||||||
|
|
||||||
public static bool TryParseUnit(World world, string unitSpec, [NotNullWhen(true)] out Unit? newUnit)
|
public static bool TryParseUnit(World world, string unitSpec, [NotNullWhen(true)] out Unit? newUnit)
|
||||||
{
|
{
|
||||||
newUnit = null;
|
newUnit = null;
|
||||||
|
|
|
@ -198,6 +198,47 @@ public class OrderParserTest
|
||||||
Assert.That(actual, Is.EqualTo(expected), "Unexpected parse results");
|
Assert.That(actual, Is.EqualTo(expected), "Unexpected parse results");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IEnumerable<TestCaseData> ConvoyRegexMatchesTestCases()
|
||||||
|
{
|
||||||
|
// Full specification
|
||||||
|
yield return Test(
|
||||||
|
"Fleet a-Nth/w@0 c A a-London/l@0 - a-Belgium/l@0",
|
||||||
|
"Fleet", "a", "Nth", "w", "0", "c", "A", "a", "London", "l", "0", "-", "a", "Belgium", "l", "0");
|
||||||
|
// Case insensitivity
|
||||||
|
yield return Test(
|
||||||
|
"fleet B-nth/W@0 CONVOYS a B-lon/L@0 MOVE TO B-bel/L@0",
|
||||||
|
"fleet", "B", "nth", "W", "0", "CONVOYS", "a", "B", "lon", "L", "0", "MOVE TO", "B", "bel", "L", "0");
|
||||||
|
// All optionals missing
|
||||||
|
yield return Test(
|
||||||
|
"TYN c ROM - TUN",
|
||||||
|
"", "", "TYN", "", "", "c", "", "", "ROM", "", "", "-", "", "TUN", "", "");
|
||||||
|
// No confusion of unit type and timeline
|
||||||
|
yield return Test(
|
||||||
|
"F A-BOT C FIN - A-LVN",
|
||||||
|
"F", "A", "BOT", "", "", "C", "", "", "FIN", "", "", "-", "A", "LVN", "", "");
|
||||||
|
// Elements with spaces
|
||||||
|
yield return Test(
|
||||||
|
"Western Mediterranean Sea convoys Spain move to North Africa",
|
||||||
|
"", "", "Western Mediterranean Sea", "", "", "convoys", "", "", "Spain", "", "", "move to", "", "North Africa", "", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCaseSource(nameof(ConvoyRegexMatchesTestCases))]
|
||||||
|
public void ConvoyRegexMatches(string order, string[] expected)
|
||||||
|
{
|
||||||
|
OrderParser re = new(World.WithStandardMap());
|
||||||
|
var match = re.Convoy.Match(order);
|
||||||
|
Assert.True(match.Success, "Match failed");
|
||||||
|
var (type, timeline, province, location, turn, convoyVerb,
|
||||||
|
targetType, targetTimeline, targetProvince, targetLocation, targetTurn, moveVerb,
|
||||||
|
destTimeline, destProvince, destLocation, destTurn) = OrderParser.ParseConvoy(match);
|
||||||
|
string[] actual = [type, timeline, province, location, turn, convoyVerb,
|
||||||
|
targetType, targetTimeline, targetProvince, targetLocation, targetTurn, moveVerb,
|
||||||
|
destTimeline, destProvince, destLocation, destTurn];
|
||||||
|
// Use EquivalentTo for more detailed error message
|
||||||
|
Assert.That(actual, Is.EquivalentTo(expected), "Unexpected parse results");
|
||||||
|
Assert.That(actual, Is.EqualTo(expected), "Unexpected parse results");
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void OrderParsingTest()
|
public void OrderParsingTest()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue