Files

33 lines
1.1 KiB
C#

namespace GameCli;
/// <summary>
/// Reward = -distance_to_target
/// - λ_v · speed
/// - λ_θ · |wrap(angle)|
/// - λ_fuel · engine_on
/// The angle is wrapped to [-π, π] so a ship that has completed N revolutions
/// gets the same upright-penalty as a physically identical pose that hasn't.
/// Coefficients are public so training scripts can log/inspect them.
/// </summary>
public static class Reward
{
public const float LambdaVelocity = 0.10f;
public const float LambdaAngle = 0.10f;
public const float LambdaFuel = 0.03f;
public static float Compute(ShipState s, (float X, float Y) target, int action)
{
float dx = target.X - s.X;
float dy = target.Y - s.Y;
float distance = MathF.Sqrt(dx * dx + dy * dy);
float speed = MathF.Sqrt(s.VX * s.VX + s.VY * s.VY);
float wrapped = MathF.Atan2(MathF.Sin(s.Angle), MathF.Cos(s.Angle));
float engineOn = action == Physics.ActionNoop ? 0f : 1f;
return -distance
- LambdaVelocity * speed
- LambdaAngle * MathF.Abs(wrapped)
- LambdaFuel * engineOn;
}
}