Files

99 lines
2.7 KiB
C#

using System.Text.Json;
using GameCli;
// Deterministic PRNG for start-pose randomization on reset.
// Seeded fresh on each reset if the caller supplies a seed.
var rng = new Random();
// Current world state and step counter. Reset on {"cmd":"reset"}.
var ship = ShipState.AtCenter();
int stepCount = 0;
int lastAction = 0;
// --- Startup handshake ---------------------------------------------------
var init = new InitMessage
{
Init = new InitPayload
{
World = new[] { 1f, 1f },
Dt = Physics.Dt,
ObsDim = Observation.Dim,
NActions = 4,
},
};
Console.WriteLine(JsonSerializer.Serialize(init, ProtocolJsonContext.Default.InitMessage));
Console.Out.Flush();
// --- Read-line loop ------------------------------------------------------
string? line;
while ((line = Console.In.ReadLine()) is not null)
{
if (line.Length == 0) continue;
StepInput? input;
try
{
input = JsonSerializer.Deserialize(line, ProtocolJsonContext.Default.StepInput);
}
catch (JsonException ex)
{
Console.Error.WriteLine($"invalid json: {ex.Message}");
continue;
}
if (input is null) continue;
// Reset command.
if (input.Cmd == "reset")
{
if (input.Seed is int seed) rng = new Random(seed);
ship = RandomStartPose(rng);
stepCount = 0;
lastAction = 0;
WriteObservation((0.5f, 0.5f), reward: 0f, done: false);
continue;
}
// Step command.
int action = input.Action ?? 0;
var target = (input.Target is { Length: >= 2 })
? (input.Target[0], input.Target[1])
: (0.5f, 0.5f);
ship = Physics.Step(ship, action);
lastAction = action;
stepCount++;
float reward = Reward.Compute(ship, target, action);
WriteObservation(target, reward, done: false);
}
// --- Helpers -------------------------------------------------------------
void WriteObservation((float X, float Y) target, float reward, bool done)
{
var output = new StepOutput
{
Obs = Observation.Build(ship, target),
State = new ShipStateDto
{
X = ship.X,
Y = ship.Y,
Angle = ship.Angle,
Engine = lastAction,
},
Reward = reward,
Done = done,
Step = stepCount,
};
Console.WriteLine(JsonSerializer.Serialize(output, ProtocolJsonContext.Default.StepOutput));
Console.Out.Flush();
}
static ShipState RandomStartPose(Random rng)
{
// Random position in a comfortable box; zero velocity, near-upright.
float x = 0.2f + (float)rng.NextDouble() * 0.6f;
float y = 0.2f + (float)rng.NextDouble() * 0.4f;
float angle = ((float)rng.NextDouble() - 0.5f) * 0.4f; // ±0.2 rad
return new ShipState(x, y, 0f, 0f, angle, 0f);
}