using System; namespace AfterHours.Economy { /// /// Reine Preis-/Nachfragelogik. Engine-frei und damit testbar. /// Keine UnityEngine-Referenzen in dieser Datei. /// public static class PricingService { /// Ab diesem Aufschlag über Empfehlung kauft niemand mehr. public const float RejectionThreshold = 1.75f; /// /// Kaufwahrscheinlichkeit relativ zum empfohlenen Preis. /// 1.0 bei Empfehlungspreis oder darunter, 0.0 ab RejectionThreshold. /// Dazwischen quadratisch abfallend – kleine Aufschläge tun kaum weh, /// große brechen die Nachfrage schnell ein. /// public static float PurchaseProbability(float askingPrice, float recommendedPrice) { if (recommendedPrice <= 0f) throw new ArgumentOutOfRangeException(nameof(recommendedPrice)); if (askingPrice <= 0f) return 1f; float ratio = askingPrice / recommendedPrice; if (ratio <= 1f) return 1f; if (ratio >= RejectionThreshold) return 0f; float t = (ratio - 1f) / (RejectionThreshold - 1f); // 0..1 return 1f - (t * t); } /// Marge in Prozent des Verkaufspreises. public static float MarginRatio(float askingPrice, float wholesalePrice) { if (askingPrice <= 0f) return 0f; return (askingPrice - wholesalePrice) / askingPrice; } /// /// Erwarteter Deckungsbeitrag pro angebotenem Stück. /// Nützlich für den späteren "Preis-Optimum"-Hinweis im Preis-UI. /// public static float ExpectedProfitPerUnit(float askingPrice, float recommendedPrice, float wholesalePrice) { return PurchaseProbability(askingPrice, recommendedPrice) * (askingPrice - wholesalePrice); } } }