From 43a2517a95fc7584007a25042a40eeb58156b466 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Wed, 28 Aug 2024 00:45:38 +0000 Subject: [PATCH] Fix unit declaration commands --- MultiversalDiplomacy/Model/OrderParser.cs | 50 ++++++++++++++--------- MultiversalDiplomacyTests/ReplTest.cs | 2 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/MultiversalDiplomacy/Model/OrderParser.cs b/MultiversalDiplomacy/Model/OrderParser.cs index 90e6472..a1e96f6 100644 --- a/MultiversalDiplomacy/Model/OrderParser.cs +++ b/MultiversalDiplomacy/Model/OrderParser.cs @@ -34,14 +34,22 @@ public class OrderParser(World world) public const string ViaConvoy = "(convoy|via convoy|by convoy)"; - public Regex PowerCommand = new($"^{world.Map.PowerRegex}(?:[:])? (.*)$"); + public Regex UnitDeclaration = new( + $"^{world.Map.PowerRegex} {Type} {world.Map.ProvinceRegex}(?:{SlashLocation}|{ParenLocation})?$", + RegexOptions.IgnoreCase); public static ( string power, - string command) - ParsePowerCommand(Match match) => ( + string type, + string province, + string location) + ParseUnitDeclaration(Match match) => ( match.Groups[1].Value, - match.Groups[2].Value); + match.Groups[2].Value, + match.Groups[3].Value, + match.Groups[4].Value.Length > 0 + ? match.Groups[4].Value + : match.Groups[5].Value); public Regex Hold => new( $"^{UnitSpec} {HoldVerb}$", @@ -178,27 +186,29 @@ public class OrderParser(World world) public static bool TryParseUnit(World world, string unitSpec, [NotNullWhen(true)] out Unit? newUnit) { newUnit = null; + OrderParser re = new(world); - Regex reUnit = new( - $"^{world.Map.PowerRegex} {Type} {world.Map.ProvinceRegex}(?:{SlashLocation}|{ParenLocation})?$"); - Match match = reUnit.Match(unitSpec); - if (!match.Success) { - return false; - } + Match match = re.UnitDeclaration.Match(unitSpec); + if (!match.Success) return false; + var unit = ParseUnitDeclaration(match); - string power = world.Map.Powers.First(p => p.EqualsAnyCase(match.Groups[1].Value)); + string power = world.Map.Powers.First(p => p.EqualsAnyCase(unit.power)); - string typeName = Enum.GetNames().First(name => name.StartsWithAnyCase(match.Groups[2].Value)); + string typeName = Enum.GetNames().First(name => name.StartsWithAnyCase(unit.type)); UnitType type = Enum.Parse(typeName); - Province province = world.Map.Provinces.First(prov - => prov.Name.EqualsAnyCase(match.Groups[3].Value) - || prov.Abbreviations.Any(abv => abv.EqualsAnyCase(match.Groups[3].Value))); - - string locationName = match.Groups[4].Length > 0 ? match.Groups[4].Value : match.Groups[5].Value; - Location location = province.Locations.First(loc - => loc.Name.StartsWithAnyCase(locationName) - || loc.Abbreviation.StartsWithAnyCase(locationName)); + Province province = world.Map.Provinces.First(prov => prov.Is(unit.province)); + Location? location; + if (unit.location.Length > 0) { + location = province.Locations.FirstOrDefault(loc => loc!.Is(unit.location), null); + } else { + location = type switch { + UnitType.Army => province.Locations.FirstOrDefault(loc => loc.Type == LocationType.Land), + UnitType.Fleet => province.Locations.FirstOrDefault(loc => loc.Type == LocationType.Water), + _ => null, + }; + } + if (location is null) return false; newUnit = Unit.Build(location.Key, Season.First, power, type); return true; diff --git a/MultiversalDiplomacyTests/ReplTest.cs b/MultiversalDiplomacyTests/ReplTest.cs index 2d81caf..23f7935 100644 --- a/MultiversalDiplomacyTests/ReplTest.cs +++ b/MultiversalDiplomacyTests/ReplTest.cs @@ -16,7 +16,7 @@ public class ReplTest repl[""" unit Germany A Munich unit Austria Army Tyrolia - unit England F London + unit England F Lon """].Ready(); Assert.That(repl.Handler, Is.TypeOf());