From 621dd27323a8343b1edf9a4e942bd2fbe4b2ba0c Mon Sep 17 00:00:00 2001 From: Chomp Date: Tue, 4 Feb 2025 19:03:47 +0000 Subject: [PATCH] Tidied up `ProbabilityObjectArray` --- .../Core/Controllers/InsuranceController.cs | 2 +- .../Core/Generators/LocationLootGenerator.cs | 6 +- .../Collections/ProbabilityObjectArray.cs | 196 ++++++++++-------- 3 files changed, 108 insertions(+), 96 deletions(-) diff --git a/Libraries/Core/Controllers/InsuranceController.cs b/Libraries/Core/Controllers/InsuranceController.cs index 1c69eef8..cc939be7 100644 --- a/Libraries/Core/Controllers/InsuranceController.cs +++ b/Libraries/Core/Controllers/InsuranceController.cs @@ -471,7 +471,7 @@ public class InsuranceController( var countOfAttachmentsToRemove = GetAttachmentCountToRemove(weightedAttachmentByPrice, traderId); // Create prob array and add all attachments with rouble price as the weight - var attachmentsProbabilityArray = new ProbabilityObjectArray, string, double?>(_mathUtil, _cloner, []); + var attachmentsProbabilityArray = new ProbabilityObjectArray, string, double?>(_mathUtil, _cloner); foreach (var attachmentTpl in weightedAttachmentByPrice) { attachmentsProbabilityArray.Add( diff --git a/Libraries/Core/Generators/LocationLootGenerator.cs b/Libraries/Core/Generators/LocationLootGenerator.cs index 6d2fe3b7..508ad82d 100644 --- a/Libraries/Core/Generators/LocationLootGenerator.cs +++ b/Libraries/Core/Generators/LocationLootGenerator.cs @@ -307,7 +307,7 @@ public class LocationLootGenerator( // Create probability array with all possible container ids in this group and their relative probability of spawning var containerDistribution = - new ProbabilityObjectArray, string, double>(_mathUtil, _cloner, []); + new ProbabilityObjectArray, string, double>(_mathUtil, _cloner); foreach (var x in containerIds) { var value = containerData.ContainerIdsWithProbability[x]; @@ -556,7 +556,7 @@ public class LocationLootGenerator( { // Create probability array to calcualte the total count of lootable items inside container var itemCountArray = - new ProbabilityObjectArray, int, float?>(_mathUtil, _cloner, []); + new ProbabilityObjectArray, int, float?>(_mathUtil, _cloner); var countDistribution = staticLootDist[containerTypeId]?.ItemCountDistribution; if (countDistribution is null) { @@ -600,7 +600,7 @@ public class LocationLootGenerator( var seasonalItemTplBlacklist = _seasonalEventService.GetInactiveSeasonalEventItems(); var itemDistribution = - new ProbabilityObjectArray, string, float?>(_mathUtil, _cloner, []); + new ProbabilityObjectArray, string, float?>(_mathUtil, _cloner); var itemContainerDistribution = staticLootDist[containerTypeId]?.ItemDistribution; if (itemContainerDistribution is null) diff --git a/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs b/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs index b8ada3df..0d5630c2 100644 --- a/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs +++ b/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs @@ -1,111 +1,119 @@ using Core.Utils.Cloners; using System.Text.Json.Serialization; -using Microsoft.AspNetCore.Components.Web; namespace Core.Utils.Collections; -/** - * Array of ProbabilityObjectArray which allow to randomly draw of the contained objects - * based on the relative probability of each of its elements. - * The probabilities of the contained element is not required to be normalized. - * - * Example: - * po = new ProbabilityObjectArray( - * new ProbabilityObject("a", 5), - * new ProbabilityObject("b", 1), - * new ProbabilityObject("c", 1) - * ); - * res = po.draw(10000); - * // count the elements which should be distributed according to the relative probabilities - * res.filter(x => x==="b").reduce((sum, x) => sum + 1 , 0) - */ -public class ProbabilityObjectArray : List where T : ProbabilityObject +/// +/// Array of ProbabilityObjectArray which allow to randomly draw of the contained objects +/// based on the relative probability of each of its elements. +/// The probabilities of the contained element is not required to be normalized. +/// +/// Example: +/// po = new ProbabilityObjectArray( +/// new ProbabilityObject("a", 5), +/// new ProbabilityObject("b", 1), +/// new ProbabilityObject("c", 1) +/// ); +/// res = po.draw(10000); +/// // count the elements which should be distributed according to the relative probabilities +/// res.filter(x => x==="b").reduce((sum, x) => sum + 1 , 0) +/// +/// +/// +/// +public class ProbabilityObjectArray : List where T : ProbabilityObject { - private MathUtil _mathUtil; - private ICloner _cloner; + private readonly MathUtil _mathUtil; + private readonly ICloner _cloner; public ProbabilityObjectArray( MathUtil mathUtil, ICloner cloner, - ICollection items - ) : base(items) + ICollection? items = null + ) : base(items ?? []) { _mathUtil = mathUtil; _cloner = cloner; } - /** - * Calculates the normalized cumulative probability of the ProbabilityObjectArray's elements normalized to 1 - * @param {array} probValues The relative probability values of which to calculate the normalized cumulative sum - * @returns {array} Cumulative Sum normalized to 1 - */ + /// + /// Calculates the normalized cumulative probability of the ProbabilityObjectArray's elements normalized to 1 + /// + /// The relative probability values of which to calculate the normalized cumulative sum + /// Cumulative Sum normalized to 1 public List CumulativeProbability(List probValues) { var sum = _mathUtil.ListSum(probValues); var probCumsum = _mathUtil.ListCumSum(probValues); probCumsum = _mathUtil.ListProduct(probCumsum, 1D / sum); + return probCumsum; } + /// + /// Filter What is inside ProbabilityObjectArray + /// + /// + /// Filtered results public ProbabilityObjectArray Filter(Predicate> predicate) { - var filtered = new ProbabilityObjectArray(_mathUtil, _cloner, new List()); + var result = new ProbabilityObjectArray(_mathUtil, _cloner, new List()); foreach (var probabilityObject in this) - { if (predicate.Invoke(probabilityObject)) - filtered.Add(probabilityObject); - } - return filtered; + { + result.Add(probabilityObject); + } + + return result; } - - /** - * Clone this ProbabilitObjectArray - * @returns {ProbabilityObjectArray} Deep Copy of this ProbabilityObjectArray - */ + + /// + /// Deep clone this ProbabilityObjectArray + /// + /// Deep Copy of ProbabilityObjectArray public ProbabilityObjectArray Clone() { var clone = _cloner.Clone(this); - var probabliltyObjects = new ProbabilityObjectArray( + var probabilityObjects = new ProbabilityObjectArray( _mathUtil, _cloner, new List() ); - probabliltyObjects.AddRange(clone); - return probabliltyObjects; + probabilityObjects.AddRange(clone); + + return probabilityObjects; } - /** - * Drop an element from the ProbabilityObjectArray - * - * @param {string} key The key of the element to drop - * @returns {ProbabilityObjectArray} ProbabilityObjectArray without the dropped element - */ + /// + /// Drop an element from the ProbabilityObjectArray + /// + /// The key of the element to drop + /// ProbabilityObjectArray without the dropped element public ProbabilityObjectArray Drop(K key) { return (ProbabilityObjectArray)this.Where((r) => !r.Key?.Equals(key) ?? false); } - /** - * Return the data field of a element of the ProbabilityObjectArray - * @param {string} key The key of the element whose data shall be retrieved - * @returns {object} The data object - */ + /// + /// Return the data field of an element of the ProbabilityObjectArray + /// + /// The key of the element whose data shall be retrieved + /// Stored data object public V? Data(K key) { var element = this.FirstOrDefault(r => r.Key?.Equals(key) ?? false); return element == null ? default : element.Data; } - /** - * Get the relative probability of an element by its key - * - * Example: - * po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1)) - * po.maxProbability() // returns 5 - * - * @param {string} key The key of the element whose relative probability shall be retrieved - * @return {number} The relative probability - */ + /// + /// Get the relative probability of an element by its key + /// + /// Example: + /// po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1)) + /// po.maxProbability() // returns 5 + /// + /// Key of element whose relative probability shall be retrieved + /// The relative probability public double? Probability(K key) { var element = this.FirstOrDefault(r => r.Key.Equals(key)); @@ -123,21 +131,19 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje */ public double MaxProbability() { - return this.Select(x => x.RelativeProbability).Max(); + return this.Max(x => x.RelativeProbability).Value; } - /** - * Get the minimum relative probability out of a ProbabilityObjectArray - * - * Example: - * po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1)) - * po.minProbability() // returns 1 - * - * @return {number} the minimum value of all relative probabilities in this ProbabilityObjectArray - */ + /// + /// Get the minimum relative probability out of a ProbabilityObjectArray + /// * Example: + /// po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1)) + /// po.minProbability() // returns 1 + /// + /// the minimum value of all relative probabilities in this ProbabilityObjectArray public double MinProbability() { - return this.Select(x => x.RelativeProbability).Min(); + return this.Min(x => x.RelativeProbability.Value); } /** @@ -160,7 +166,7 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje new { probArray = new List(), keyArray = new List() }, (acc, x) => { - acc.probArray.Add(x.RelativeProbability); + acc.probArray.Add(x.RelativeProbability.Value); acc.keyArray.Add(x.Key); return acc; } @@ -200,34 +206,40 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje } } -/** - * A ProbabilityObject which is use as an element to the ProbabilityObjectArray array - * It contains a key, the relative probability as well as optional data. - */ +/// +/// A ProbabilityObject which is use as an element to the ProbabilityObjectArray array +/// It contains a key, the relative probability as well as optional data. +/// +/// +/// public class ProbabilityObject { public ProbabilityObject() - { } - - [JsonPropertyName("key")] - public K Key { get; set; } - - [JsonPropertyName("relativeProbability")] - public double RelativeProbability { get; set; } - - [JsonPropertyName("data")] - public V? Data { get; set; } + { + } /** - * varructor for the ProbabilityObject - * @param {string} key The key of the element - * @param {number} relativeProbability The relative probability of this element - * @param {any} data Optional data attached to the element - */ - public ProbabilityObject(K key, double relativeProbability, V? data) + * constructor for the ProbabilityObject + * @param {string} key The key of the element + * @param {number} relativeProbability The relative probability of this element + * @param {any} data Optional data attached to the element + */ + public ProbabilityObject(K key, double? relativeProbability, V? data) { Key = key; RelativeProbability = relativeProbability; Data = data; } + + [JsonPropertyName("key")] + public K? Key { get; set; } + + /// + /// Weighting of key compared to other ProbabilityObjects + /// + [JsonPropertyName("relativeProbability")] + public double? RelativeProbability { get; set; } + + [JsonPropertyName("data")] + public V? Data { get; set; } }