Add order parsing regex

This commit is contained in:
Tim Van Baak 2024-08-20 14:39:49 +00:00
parent ea366220eb
commit 1689d2e9b1
2 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,82 @@
using System.Text.RegularExpressions;
namespace MultiversalDiplomacy.Model;
public class OrderRegex(World world)
{
static IEnumerable<string> AllProvinceNames(Province prov) => prov.Abbreviations.Append(prov.Name);
public string Power = $"({string.Join("|", world.Powers)})";
public string Province = $"({string.Join("|", world.Provinces.SelectMany(AllProvinceNames))})";
public const string Type = "(A|F|Army|Fleet)";
public const string Timeline = "([A-Za-z]+)";
public const string Turn = "([0-9]+)";
public const string SlashLocation = "(?:/([A-Za-z]+))";
public const string ParenLocation = "(?:\\(([A-Za-z ]+)\\))";
public string FullLocation => $"(?:{Timeline}-)?{Province}(?:{SlashLocation}|{ParenLocation})?(?:@{Turn})?";
public string Unit => $"(?:(?:{Power} )?{Type} )?{FullLocation}";
public const string HoldVerb = "(h|hold|holds)";
public const string MoveVerb = "(-|(?:->)|(?:=>)|(?:attack(?:s)?)|(?:move(?:s)?(?: to)?))";
public Regex Hold => new($"^{Unit} {HoldVerb}$");
public static (
string power,
string type,
string timeline,
string province,
string location,
string turn,
string verb)
ParseHold(Match match)
=> (match.Groups[1].Value,
match.Groups[2].Value,
match.Groups[3].Value,
match.Groups[4].Value,
match.Groups[5].Length > 0
? match.Groups[5].Value
: match.Groups[6].Value,
match.Groups[7].Value,
match.Groups[8].Value);
public Regex Move => new($"^{Unit} {MoveVerb} {FullLocation}$");
public static (
string power,
string type,
string timeline,
string province,
string location,
string turn,
string verb,
string timeline2,
string province2,
string location2,
string turn2)
ParseMove(Match match)
=> (match.Groups[1].Value,
match.Groups[2].Value,
match.Groups[3].Value,
match.Groups[4].Value,
match.Groups[5].Length > 0
? 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 > 1
? match.Groups[11].Value
: match.Groups[12].Value,
match.Groups[13].Value);
}

View File

@ -0,0 +1,54 @@
using System.Text.RegularExpressions;
using NUnit.Framework;
using MultiversalDiplomacy.Model;
namespace MultiversalDiplomacyTests;
public class RegexTest
{
[Test]
public void UnitTokenizer()
{
World world = World.WithStandardMap();
OrderRegex re = new(world);
var match = re.Hold.Match("Germany Army a-Munich/l@0 holds");
Assert.That(match.Success, Is.True);
var hold = OrderRegex.ParseHold(match);
Assert.That(hold.power, Is.EqualTo("Germany"));
Assert.That(hold.type, Is.EqualTo("Army"));
Assert.That(hold.timeline, Is.EqualTo("a"));
Assert.That(hold.province, Is.EqualTo("Munich"));
Assert.That(hold.location, Is.EqualTo("l"));
Assert.That(hold.turn, Is.EqualTo("0"));
Assert.That(hold.verb, Is.EqualTo("holds"));
match = re.Hold.Match("F Venice hold");
Assert.That(match.Success, Is.True);
hold = OrderRegex.ParseHold(match);
Assert.That(hold.power, Is.EqualTo(""));
Assert.That(hold.type, Is.EqualTo("F"));
Assert.That(hold.timeline, Is.EqualTo(""));
Assert.That(hold.province, Is.EqualTo("Venice"));
Assert.That(hold.location, Is.EqualTo(""));
Assert.That(hold.turn, Is.EqualTo(""));
Assert.That(hold.verb, Is.EqualTo("hold"));
match = re.Move.Match("F Gascony - Spain(nc)");
Assert.That(match.Success, Is.True);
var move = OrderRegex.ParseMove(match);
Assert.That(move.power, Is.EqualTo(""));
Assert.That(move.type, Is.EqualTo("F"));
Assert.That(move.timeline, Is.EqualTo(""));
Assert.That(move.province, Is.EqualTo("Gascony"));
Assert.That(move.location, Is.EqualTo(""));
Assert.That(move.turn, Is.EqualTo(""));
Assert.That(move.verb, Is.EqualTo("-"));
Assert.That(move.timeline2, Is.EqualTo(""));
Assert.That(move.province2, Is.EqualTo("Spain"));
Assert.That(move.location2, Is.EqualTo("nc"));
Assert.That(move.turn2, Is.EqualTo(""));
}
}