This commit is contained in:
2026-08-10 19:23:04 +02:00
commit 404d15a56c
134 changed files with 5374 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
using System;
namespace AfterHours.Economy
{
/// <summary>
/// Reine Preis-/Nachfragelogik. Engine-frei und damit testbar.
/// Keine UnityEngine-Referenzen in dieser Datei.
/// </summary>
public static class PricingService
{
/// <summary>Ab diesem Aufschlag über Empfehlung kauft niemand mehr.</summary>
public const float RejectionThreshold = 1.75f;
/// <summary>
/// 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.
/// </summary>
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);
}
/// <summary>Marge in Prozent des Verkaufspreises.</summary>
public static float MarginRatio(float askingPrice, float wholesalePrice)
{
if (askingPrice <= 0f) return 0f;
return (askingPrice - wholesalePrice) / askingPrice;
}
/// <summary>
/// Erwarteter Deckungsbeitrag pro angebotenem Stück.
/// Nützlich für den späteren "Preis-Optimum"-Hinweis im Preis-UI.
/// </summary>
public static float ExpectedProfitPerUnit(float askingPrice, float recommendedPrice, float wholesalePrice)
{
return PurchaseProbability(askingPrice, recommendedPrice) * (askingPrice - wholesalePrice);
}
}
}