diff --git a/MultiversalDiplomacy/Model/OrderParser.cs b/MultiversalDiplomacy/Model/OrderParser.cs index 7ffda4e..51de6b8 100644 --- a/MultiversalDiplomacy/Model/OrderParser.cs +++ b/MultiversalDiplomacy/Model/OrderParser.cs @@ -227,7 +227,7 @@ public class OrderParser(World world) } else if (re.SupportMove.Match(command) is Match smoveMatch && smoveMatch.Success) { return TryParseSupportMoveOrder(world, power, smoveMatch, out order); } else { - throw new NotImplementedException(); + return false; } } diff --git a/MultiversalDiplomacy/Script/AdjudicationQueryScriptHandler.cs b/MultiversalDiplomacy/Script/AdjudicationQueryScriptHandler.cs index e557731..588494a 100644 --- a/MultiversalDiplomacy/Script/AdjudicationQueryScriptHandler.cs +++ b/MultiversalDiplomacy/Script/AdjudicationQueryScriptHandler.cs @@ -1,10 +1,14 @@ +using System.Text.RegularExpressions; + using MultiversalDiplomacy.Adjudicate; using MultiversalDiplomacy.Model; +using MultiversalDiplomacy.Orders; namespace MultiversalDiplomacy.Script; public class AdjudicationQueryScriptHandler( Action WriteLine, + List validations, World world, IPhaseAdjudicator adjudicator, bool strict = false) @@ -12,6 +16,8 @@ public class AdjudicationQueryScriptHandler( { public string Prompt => "valid> "; + public List Validations { get; } = validations; + public World World { get; private set; } = world; /// @@ -67,10 +73,40 @@ public class AdjudicationQueryScriptHandler( return false; case "order-valid": - // Assert order was valid - case "order-invalid": - // Assert order was invalid + OrderParser re = new(World); + Regex prov = new($"^{re.FullLocation}$", RegexOptions.IgnoreCase); + Match match = prov.Match(args[1]); + if (!match.Success) { + WriteLine($"Could not parse province from \"{args[1]}\""); + return !Strict; + } + + string timeline = match.Groups[1].Length > 0 + ? match.Groups[1].Value + : Season.First.Timeline; + var seasonsInTimeline = World.Timelines.Seasons.Where(season => season.Timeline == timeline); + if (!seasonsInTimeline.Any()) return false; + + int turn = match.Groups[4].Length > 0 + ? int.Parse(match.Groups[4].Value) + // If turn is unspecified, use the second-latest turn in the timeline, + // since we want to assert against the subjects of the orders just adjudicated, + // and adjudication created a new set of seasons. + : seasonsInTimeline.Max(season => season.Turn) - 1; + Season season = new(timeline, turn); + + Province province = World.Map.Provinces.Single(province => province.Is(match.Groups[2].Value)); + + var matching = Validations.Where(val + => val.Order is UnitOrder order + && order.Unit.Season == season + && World.Map.GetLocation(order.Unit.Location).ProvinceName == province.Name); + if (!matching.Any()) return false; + + return args[0] == "order-valid" + ? matching.First().Valid + : !matching.First().Valid; case "has-past": // Assert a timeline's past diff --git a/MultiversalDiplomacy/Script/GameScriptHandler.cs b/MultiversalDiplomacy/Script/GameScriptHandler.cs index e3b41fc..b4e3a98 100644 --- a/MultiversalDiplomacy/Script/GameScriptHandler.cs +++ b/MultiversalDiplomacy/Script/GameScriptHandler.cs @@ -44,7 +44,7 @@ public class GameScriptHandler( .ToList(); var adjudication = adjudicator.AdjudicateOrders(World, validOrders); var newWorld = adjudicator.UpdateWorld(World, adjudication); - return new AdjudicationQueryScriptHandler(WriteLine, newWorld, adjudicator, Strict); + return new AdjudicationQueryScriptHandler(WriteLine, validation, newWorld, adjudicator, Strict); } // "===" submits the orders and moves immediately to taking the next set of orders