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 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<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);
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;

View File

@ -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<SetupScriptHandler>());