Chessistics/Scripts/Automation/SnapshotSerializer.cs

124 lines
4.2 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
using Chessistics.Engine.Model;
namespace Chessistics.Scripts.Automation;
/// <summary>
/// Serializes BoardSnapshot into plain JSON so the agent can reason about game state.
/// </summary>
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<JsonNode?>()),
["demands"] = new JsonArray(snap.Demands.Select(SerializeDemand).ToArray<JsonNode?>()),
["transformers"] = new JsonArray(snap.Transformers.Select(SerializeTransformer).ToArray<JsonNode?>()),
["pieces"] = new JsonArray(snap.Pieces.Select(SerializePiece).ToArray<JsonNode?>()),
["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<PieceKind, int> 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;
}
}