namespace Mr.BrickAdventures.Progression; /// /// A non-negative quantity of coins. Amounts only — there is no signed coin value; a shortfall is /// a failed subtraction the caller must handle, never a negative total. /// public readonly struct Coins : IEquatable { public int Value { get; } private Coins(int value) => Value = value; public static Coins Of(int value) => value < 0 ? throw new ArgumentOutOfRangeException(nameof(value), value, "Coins cannot be negative.") : new Coins(value); /// /// Subtracts . Returns false when the amount exceeds what is held, /// leaving untouched rather than clamping to zero. /// public bool TrySubtract(Coins amount, out Coins remaining) { if (amount.Value > Value) { remaining = this; return false; } remaining = new Coins(Value - amount.Value); return true; } public bool Equals(Coins other) => Value == other.Value; public override bool Equals(object? obj) => obj is Coins other && Equals(other); public override int GetHashCode() => Value; public override string ToString() => Value.ToString(); }