using System.Text.RegularExpressions; using MultiversalDiplomacy.Model; using MultiversalDiplomacy.Orders; namespace MultiversalDiplomacy.Script; public class GameScriptHandler(World world, bool strict = false) : IScriptHandler { public string Prompt => "orders> "; public World World { get; private set; } = world; /// /// Whether unsuccessful commands should terminate the script. /// public bool Strict { get; } = strict; private string? CurrentPower = null; public IScriptHandler? HandleInput(string input) { if (input == "") { CurrentPower = null; return this; } if (input.StartsWith('#')) return this; // "---" submits the orders and allows queries about the outcome if (input == "---") { Console.WriteLine("Submitting orders for adjudication"); // TODO submit, validate, and adjudicate orders // TODO pass validation, adjudication, and prev/next World to next handler return new AdjudicationQueryScriptHandler(World, Strict); } // "===" submits the orders and moves immediately to taking the next set of orders // i.e. it's "---" twice if (input == "===") { Console.WriteLine("Submitting orders for adjudication"); // TODO submit, validate, and adjudicate orders // TODO replace World with updated world and return a new handler Console.WriteLine("Ready for orders"); return new GameScriptHandler(World, Strict); } // A block of orders for a single power beginning with "{name}:" if (World.Powers.FirstOrDefault(p => input.EqualsAnyCase($"{p}:"), null) is string power) { CurrentPower = power; return this; } if (TryParseOrder(input, out Order? order)) { Console.WriteLine($"Parsed order \"{input}\" but doing anything with it isn't implemented yet"); } else if (Strict) { return null; } return this; } private bool TryParseOrder(string input, out Order? order) { order = null; OrderRegex re = new(World); Match match; if ((match = re.Hold.Match(input)).Success) { var hold = OrderRegex.ParseHold(match); string power = hold.power.Length > 0 ? hold.power : CurrentPower ?? hold.power; Unit unit = World.Units.First(unit => World.Map.GetLocation(unit.Location).ProvinceName == hold.province && unit.Season.Timeline == (hold.timeline.Length > 0 ? hold.timeline : "a") && unit.Season.Turn.ToString() == (hold.turn.Length > 0 ? hold.turn : "0")); order = new HoldOrder(power, unit); return true; } else if ((match = re.Move.Match(input)).Success) { var move = OrderRegex.ParseMove(match); Unit unit = World.Units.First(unit => World.Map.GetLocation(unit.Location).ProvinceName == move.province && unit.Season.Timeline == (move.timeline.Length > 0 ? move.timeline : "a") && unit.Season.Turn.ToString() == (move.turn.Length > 0 ? move.turn : "0")); order = new MoveOrder(move.power, unit, Season.First, "l"); return true; } Console.WriteLine($"Failed to parse \"{input}\""); return false; } }