Fix unit declaration commands

This commit is contained in:
Tim Van Baak 2024-08-28 00:45:38 +00:00
parent 512c91d2de
commit 43a2517a95
2 changed files with 31 additions and 21 deletions

View File

@ -34,14 +34,22 @@ public class OrderParser(World world)
public const string ViaConvoy = "(convoy|via convoy|by convoy)"; 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 ( public static (
string power, string power,
string command) string type,
ParsePowerCommand(Match match) => ( string province,
string location)
ParseUnitDeclaration(Match match) => (
match.Groups[1].Value, 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( public Regex Hold => new(
$"^{UnitSpec} {HoldVerb}$", $"^{UnitSpec} {HoldVerb}$",
@ -178,27 +186,29 @@ public class OrderParser(World world)
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;
OrderParser re = new(world);
Regex reUnit = new( Match match = re.UnitDeclaration.Match(unitSpec);
$"^{world.Map.PowerRegex} {Type} {world.Map.ProvinceRegex}(?:{SlashLocation}|{ParenLocation})?$"); if (!match.Success) return false;
Match match = reUnit.Match(unitSpec); var unit = ParseUnitDeclaration(match);
if (!match.Success) {
return false;
}
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<UnitType>().First(name => name.StartsWithAnyCase(match.Groups[2].Value)); string typeName = Enum.GetNames<UnitType>().First(name => name.StartsWithAnyCase(unit.type));
UnitType type = Enum.Parse<UnitType>(typeName); UnitType type = Enum.Parse<UnitType>(typeName);
Province province = world.Map.Provinces.First(prov Province province = world.Map.Provinces.First(prov => prov.Is(unit.province));
=> prov.Name.EqualsAnyCase(match.Groups[3].Value) Location? location;
|| prov.Abbreviations.Any(abv => abv.EqualsAnyCase(match.Groups[3].Value))); if (unit.location.Length > 0) {
location = province.Locations.FirstOrDefault(loc => loc!.Is(unit.location), null);
string locationName = match.Groups[4].Length > 0 ? match.Groups[4].Value : match.Groups[5].Value; } else {
Location location = province.Locations.First(loc location = type switch {
=> loc.Name.StartsWithAnyCase(locationName) UnitType.Army => province.Locations.FirstOrDefault(loc => loc.Type == LocationType.Land),
|| loc.Abbreviation.StartsWithAnyCase(locationName)); 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); newUnit = Unit.Build(location.Key, Season.First, power, type);
return true; return true;

View File

@ -16,7 +16,7 @@ public class ReplTest
repl[""" repl["""
unit Germany A Munich unit Germany A Munich
unit Austria Army Tyrolia unit Austria Army Tyrolia
unit England F London unit England F Lon
"""].Ready(); """].Ready();
Assert.That(repl.Handler, Is.TypeOf<SetupScriptHandler>()); Assert.That(repl.Handler, Is.TypeOf<SetupScriptHandler>());