using System.Collections.Generic; using System.Linq; using System.Text.Json.Nodes; using Chessistics.Engine.Model; namespace Chessistics.Scripts.Automation; /// /// Serializes BoardSnapshot into plain JSON so the agent can reason about game state. /// internal static class SnapshotSerializer { public static JsonObject Serialize(BoardSnapshot snap) { var root = new JsonObject { ["phase"] = snap.Phase.ToString(), ["turn"] = snap.TurnNumber, ["width"] = snap.Width, ["height"] = snap.Height, ["grid"] = SerializeGrid(snap.Grid, snap.Width, snap.Height), ["productions"] = new JsonArray(snap.Productions.Select(SerializeProd).ToArray()), ["demands"] = new JsonArray(snap.Demands.Select(SerializeDemand).ToArray()), ["transformers"] = new JsonArray(snap.Transformers.Select(SerializeTransformer).ToArray()), ["pieces"] = new JsonArray(snap.Pieces.Select(SerializePiece).ToArray()), ["remainingStock"] = SerializeStock(snap.RemainingStock), }; if (snap.Campaign != null) { root["campaign"] = new JsonObject { ["name"] = snap.Campaign.Name, ["currentMissionIndex"] = snap.Campaign.CurrentMissionIndex, ["completedMissions"] = new JsonArray(snap.Campaign.CompletedMissions.Select(i => (JsonNode?)JsonValue.Create(i)).ToArray()), ["availablePieceKinds"] = new JsonArray(snap.Campaign.AvailablePieceKinds.Select(k => (JsonNode?)JsonValue.Create(k.ToString())).ToArray()), ["availableLevels"] = new JsonArray(snap.Campaign.AvailableLevels .Select(u => (JsonNode?)new JsonObject { ["kind"] = u.Kind.ToString(), ["level"] = u.Level }) .ToArray()), }; } else { root["campaign"] = null; } return root; } private static JsonArray SerializeGrid(CellType[,] grid, int w, int h) { var rows = new JsonArray(); for (int r = 0; r < h; r++) { var row = new JsonArray(); for (int c = 0; c < w; c++) row.Add(grid[c, r].ToString()); rows.Add(row); } return rows; } private static JsonObject SerializeProd(ProductionSnapshot p) => new() { ["pos"] = CoordsJson(p.Position), ["name"] = p.Name, ["cargo"] = p.Cargo.ToString(), ["amount"] = p.Amount, ["buffer"] = p.BufferCount, }; private static JsonObject SerializeDemand(DemandSnapshot d) => new() { ["pos"] = CoordsJson(d.Position), ["name"] = d.Name, ["cargo"] = d.Cargo.ToString(), ["required"] = d.Required, ["deadline"] = d.Deadline, ["received"] = d.ReceivedCount, ["satisfied"] = d.IsSatisfied, ["missionIndex"] = d.MissionIndex, }; private static JsonObject SerializeTransformer(TransformerSnapshot t) => new() { ["pos"] = CoordsJson(t.Position), ["name"] = t.Name, ["inputCargo"] = t.InputCargo.ToString(), ["inputRequired"] = t.InputRequired, ["outputCargo"] = t.OutputCargo.ToString(), ["outputAmount"] = t.OutputAmount, ["inputBuffer"] = t.InputBufferCount, ["outputBuffer"] = t.OutputBufferCount, }; private static JsonObject SerializePiece(PieceSnapshot p) => new() { ["id"] = p.Id, ["kind"] = p.Kind.ToString(), ["level"] = p.Level, ["start"] = CoordsJson(p.StartCell), ["end"] = CoordsJson(p.EndCell), ["current"] = CoordsJson(p.CurrentCell), ["cargo"] = p.Cargo?.ToString(), ["cargoFilter"] = p.CargoFilter?.ToString(), ["socialStatus"] = p.SocialStatus, }; private static JsonObject SerializeStock(IReadOnlyDictionary stock) { var obj = new JsonObject(); foreach (var (k, v) in stock) obj[k.ToString()] = v; return obj; } private static JsonArray CoordsJson(Coords c) { var arr = new JsonArray(); arr.Add(c.Col); arr.Add(c.Row); return arr; } }