From de1fffb7d1eb153326102fe180b908fa3bae25aa Mon Sep 17 00:00:00 2001 From: cadon Date: Sun, 4 Feb 2024 13:28:01 +0100 Subject: [PATCH] fixed topness calculation for negative weights --- .../BreedingPlanning/BreedingPlan.cs | 23 ++-- .../BreedingPlanning/BreedingScore.cs | 15 ++- ARKBreedingStats/Form1.library.cs | 121 +++++++++++------- ARKBreedingStats/library/Creature.cs | 1 + ARKBreedingStats/library/DummyCreatures.cs | 2 +- ARKBreedingStats/uiControls/StatWeighting.cs | 8 +- 6 files changed, 99 insertions(+), 71 deletions(-) diff --git a/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs b/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs index 4d71f575..3223138f 100644 --- a/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs +++ b/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs @@ -52,7 +52,7 @@ public partial class BreedingPlan : UserControl private bool[] _enabledColorRegions; private TimeSpan _incubationTime; private Creature _chosenCreature; - private BreedingMode _breedingMode; + private BreedingScore.BreedingMode _breedingMode; public readonly StatWeighting StatWeighting; public bool BreedingPlanNeedsUpdate; private bool _speciesInfoNeedsUpdate; @@ -76,7 +76,7 @@ public BreedingPlan() for (int i = 0; i < Stats.StatsCount; i++) _statWeights[i] = 1; - _breedingMode = BreedingMode.TopStatsConservative; + _breedingMode = BreedingScore.BreedingMode.TopStatsConservative; _breedingPairs = new List(); pedigreeCreatureBest.SetIsVirtual(true); @@ -289,7 +289,7 @@ private void DoCalculateBreedingScoresAndDisplayPairs() // only consider creatures with top stats if breeding for that Creature[] females, males; - if (_breedingMode == BreedingMode.BestNextGen) + if (_breedingMode == BreedingScore.BreedingMode.BestNextGen) { females = _females; males = _males; @@ -538,7 +538,7 @@ private void DoCalculateBreedingScoresAndDisplayPairs() SetParents(0); // if breeding mode is conservative and a creature with top-stats already exists, the scoring might seem off - if (_breedingMode == BreedingMode.TopStatsConservative) + if (_breedingMode == BreedingScore.BreedingMode.TopStatsConservative) { bool bestCreatureAlreadyAvailable = true; Creature bestCreature = null; @@ -852,7 +852,7 @@ private void SetParents(int comboIndex) crW.Father = father; double probabilityBest = 1; bool totalLevelUnknown = false; // if stats are unknown, total level is as well (==> oxygen, speed) - bool topStatBreedingMode = _breedingMode == BreedingMode.TopStatsConservative || _breedingMode == BreedingMode.TopStatsLucky; + bool topStatBreedingMode = _breedingMode == BreedingScore.BreedingMode.TopStatsConservative || _breedingMode == BreedingScore.BreedingMode.TopStatsLucky; for (int s = 0; s < Stats.StatsCount; s++) { if (s == Stats.Torpidity) continue; @@ -996,7 +996,7 @@ private void radioButtonBPTopStatsCn_CheckedChanged(object sender, EventArgs e) { if (rbBPTopStatsCn.Checked) { - _breedingMode = BreedingMode.TopStatsConservative; + _breedingMode = BreedingScore.BreedingMode.TopStatsConservative; CalculateBreedingScoresAndDisplayPairs(); } } @@ -1005,7 +1005,7 @@ private void radioButtonBPTopStats_CheckedChanged(object sender, EventArgs e) { if (rbBPTopStats.Checked) { - _breedingMode = BreedingMode.TopStatsLucky; + _breedingMode = BreedingScore.BreedingMode.TopStatsLucky; CalculateBreedingScoresAndDisplayPairs(); } } @@ -1014,7 +1014,7 @@ private void radioButtonBPHighStats_CheckedChanged(object sender, EventArgs e) { if (rbBPHighStats.Checked) { - _breedingMode = BreedingMode.BestNextGen; + _breedingMode = BreedingScore.BreedingMode.BestNextGen; CalculateBreedingScoresAndDisplayPairs(); } } @@ -1108,13 +1108,6 @@ public bool IgnoreSexInBreedingPlan set => CbIgnoreSexInPlanning.Checked = value; } - public enum BreedingMode - { - BestNextGen, - TopStatsLucky, - TopStatsConservative - } - private void cbTagExcludeDefault_CheckedChanged(object sender, EventArgs e) { CalculateBreedingScoresAndDisplayPairs(); diff --git a/ARKBreedingStats/BreedingPlanning/BreedingScore.cs b/ARKBreedingStats/BreedingPlanning/BreedingScore.cs index ed3f0795..1c6c5415 100644 --- a/ARKBreedingStats/BreedingPlanning/BreedingScore.cs +++ b/ARKBreedingStats/BreedingPlanning/BreedingScore.cs @@ -31,7 +31,7 @@ public static class BreedingScore /// Array for each stat if the higher level should be considered for score: 0: consider any level, 1: consider only if odd, 2: consider only if even. /// public static List CalculateBreedingScores(Creature[] females, Creature[] males, Species species, - short[] bestPossLevels, double[] statWeights, int[] bestLevelsOfSpecies, BreedingPlan.BreedingMode breedingMode, + short[] bestPossLevels, double[] statWeights, int[] bestLevelsOfSpecies, BreedingMode breedingMode, bool considerChosenCreature, bool considerMutationLimit, int mutationLimit, ref bool creaturesMutationsFilteredOut, int offspringLevelLimit = 0, bool downGradeOffspringWithLevelHigherThanLimit = false, bool onlyBestSuggestionForFemale = false, byte[] anyOddEven = null) @@ -111,7 +111,7 @@ public static List CalculateBreedingScores(Creature[] females, Cre double weightedExpectedStatLevel = statWeights[s] * (Ark.ProbabilityInheritHigherLevel * higherLevel + Ark.ProbabilityInheritLowerLevel * lowerLevel) / 40; if (weightedExpectedStatLevel != 0) { - if (breedingMode == BreedingPlan.BreedingMode.TopStatsLucky) + if (breedingMode == BreedingMode.TopStatsLucky) { if (!ignoreTopStats && (female.levelsWild[s] == bestLevelsOfSpecies[s] || male.levelsWild[s] == bestLevelsOfSpecies[s])) { @@ -121,7 +121,7 @@ public static List CalculateBreedingScores(Creature[] females, Cre else if (bestLevelsOfSpecies[s] > 0) weightedExpectedStatLevel *= .01; } - else if (breedingMode == BreedingPlan.BreedingMode.TopStatsConservative && bestLevelsOfSpecies[s] > 0) + else if (breedingMode == BreedingMode.TopStatsConservative && bestLevelsOfSpecies[s] > 0) { bool higherIsBetter = statWeights[s] >= 0; bestPossLevels[s] = (short)(higherIsBetter ? Math.Max(female.levelsWild[s], male.levelsWild[s]) : Math.Min(female.levelsWild[s], male.levelsWild[s])); @@ -140,7 +140,7 @@ public static List CalculateBreedingScores(Creature[] females, Cre } } - if (breedingMode == BreedingPlan.BreedingMode.TopStatsConservative) + if (breedingMode == BreedingMode.TopStatsConservative) { if (topStatsMother < offspringPotentialTopStatCount && topStatsFather < offspringPotentialTopStatCount) t += offspringExpectedTopStatCount; @@ -274,5 +274,12 @@ public static int GetHigherBestLevel(int level1, int level2, byte anyOddEven) default: return Math.Max(level1, level2); } } + + public enum BreedingMode + { + BestNextGen, + TopStatsLucky, + TopStatsConservative + } } } diff --git a/ARKBreedingStats/Form1.library.cs b/ARKBreedingStats/Form1.library.cs index 862eb8c5..c83e5a80 100644 --- a/ARKBreedingStats/Form1.library.cs +++ b/ARKBreedingStats/Form1.library.cs @@ -316,8 +316,14 @@ private void CalculateTopStats(List creatures) } List[] bestCreaturesWildLevels = new List[Stats.StatsCount]; List[] bestCreaturesMutatedLevels = new List[Stats.StatsCount]; - int usedStatsCount = usedStatIndices.Count; - int usedAndConsideredStatsCount = usedAndConsideredStatIndices.Count; + var statPreferences = new StatWeighting.StatValuePreference[Stats.StatsCount]; + for (int s = 0; s < Stats.StatsCount; s++) + { + var statWeight = statWeights.Item1[s]; + statPreferences[s] = statWeight > 0 ? StatWeighting.StatValuePreference.High : + statWeight < 0 ? StatWeighting.StatValuePreference.Low : + StatWeighting.StatValuePreference.Indifferent; + } foreach (var c in speciesCreatures) { @@ -341,77 +347,80 @@ private void CalculateTopStats(List creatures) continue; } - for (int s = 0; s < usedStatsCount; s++) + foreach (var s in usedStatIndices) { - int si = usedStatIndices[s]; - var statWeight = statWeights.Item1[s]; - var statPreference = statWeight > 0 ? StatWeighting.StatValuePreference.High : - statWeight < 0 ? StatWeighting.StatValuePreference.Low : - StatWeighting.StatValuePreference.Indifferent; - - if (c.levelsWild[si] >= 0) + if (c.levelsWild[s] >= 0) { - if (statPreference == StatWeighting.StatValuePreference.Low) + if (statPreferences[s] == StatWeighting.StatValuePreference.Low) { - if (lowestLevels[si] == -1 || c.levelsWild[si] < lowestLevels[si]) + if (lowestLevels[s] == -1 || c.levelsWild[s] < lowestLevels[s]) { - bestCreaturesWildLevels[si] = new List { c }; - lowestLevels[si] = c.levelsWild[si]; + bestCreaturesWildLevels[s] = new List { c }; + lowestLevels[s] = c.levelsWild[s]; } - else if (c.levelsWild[si] == lowestLevels[si]) + else if (c.levelsWild[s] == lowestLevels[s]) { - bestCreaturesWildLevels[si].Add(c); + bestCreaturesWildLevels[s].Add(c); + } + + if (c.levelsWild[s] > highestLevels[s]) + { + highestLevels[s] = c.levelsWild[s]; } } - else if (statPreference == StatWeighting.StatValuePreference.High) + else if (statPreferences[s] == StatWeighting.StatValuePreference.High) { - if (c.levelsWild[si] > highestLevels[si]) + if (c.levelsWild[s] > highestLevels[s]) { // creature has a higher level than the current highest level // check if highest stats are only counted if odd or even if ((statWeights.Item2?[s] ?? 0) == 0 // even/odd doesn't matter - || (statWeights.Item2[s] == 1 && c.levelsWild[si] % 2 == 1) - || (statWeights.Item2[s] == 2 && c.levelsWild[si] % 2 == 0) + || (statWeights.Item2[s] == 1 && c.levelsWild[s] % 2 == 1) + || (statWeights.Item2[s] == 2 && c.levelsWild[s] % 2 == 0) ) { - bestCreaturesWildLevels[si] = new List { c }; - highestLevels[si] = c.levelsWild[si]; + bestCreaturesWildLevels[s] = new List { c }; + highestLevels[s] = c.levelsWild[s]; } } - else if (c.levelsWild[si] == highestLevels[si]) + else if (c.levelsWild[s] == highestLevels[s]) + { + bestCreaturesWildLevels[s].Add(c); + } + if (lowestLevels[s] == -1 || c.levelsWild[s] < lowestLevels[s]) { - bestCreaturesWildLevels[si].Add(c); + lowestLevels[s] = c.levelsWild[s]; } } } - if (c.levelsMutated != null && c.levelsMutated[si] >= 0) + if (c.levelsMutated != null && c.levelsMutated[s] >= 0) { - if (statPreference == StatWeighting.StatValuePreference.Low) + if (statPreferences[s] == StatWeighting.StatValuePreference.Low) { - if (c.levelsMutated[si] < lowestMutationLevels[si]) + if (c.levelsMutated[s] < lowestMutationLevels[s]) { - bestCreaturesMutatedLevels[si] = new List { c }; - lowestMutationLevels[si] = c.levelsMutated[si]; + bestCreaturesMutatedLevels[s] = new List { c }; + lowestMutationLevels[s] = c.levelsMutated[s]; } - else if (c.levelsMutated[si] == lowestMutationLevels[si]) + else if (c.levelsMutated[s] == lowestMutationLevels[s]) { - if (bestCreaturesMutatedLevels[si] == null) - bestCreaturesMutatedLevels[si] = new List { c }; - else bestCreaturesMutatedLevels[si].Add(c); + if (bestCreaturesMutatedLevels[s] == null) + bestCreaturesMutatedLevels[s] = new List { c }; + else bestCreaturesMutatedLevels[s].Add(c); } } - else if (statPreference == StatWeighting.StatValuePreference.High - && c.levelsMutated[si] > 0) + else if (statPreferences[s] == StatWeighting.StatValuePreference.High + && c.levelsMutated[s] > 0) { - if (c.levelsMutated[si] > 0 && c.levelsMutated[si] > highestMutationLevels[si]) + if (c.levelsMutated[s] > 0 && c.levelsMutated[s] > highestMutationLevels[s]) { - bestCreaturesMutatedLevels[si] = new List { c }; - highestMutationLevels[si] = c.levelsMutated[si]; + bestCreaturesMutatedLevels[s] = new List { c }; + highestMutationLevels[s] = c.levelsMutated[s]; } - else if (c.levelsMutated[si] == highestMutationLevels[si]) + else if (c.levelsMutated[s] == highestMutationLevels[s]) { - bestCreaturesMutatedLevels[si].Add(c); + bestCreaturesMutatedLevels[s].Add(c); } } } @@ -427,11 +436,21 @@ private void CalculateTopStats(List creatures) // set topness of each creature (== mean wildLevels/mean top wildLevels in permille) int sumTopLevels = 0; - for (int s = 0; s < usedAndConsideredStatsCount; s++) + foreach (var s in usedAndConsideredStatIndices) { - int si = usedAndConsideredStatIndices[s]; - if (highestLevels[si] > 0) - sumTopLevels += highestLevels[si]; + switch (statPreferences[s]) + { + case StatWeighting.StatValuePreference.Indifferent: + continue; + case StatWeighting.StatValuePreference.Low: + if (highestLevels[s] > 0 && lowestLevels[s] != 0) + sumTopLevels += highestLevels[s] - lowestLevels[s]; + break; + case StatWeighting.StatValuePreference.High: + if (highestLevels[s] > 0) + sumTopLevels += highestLevels[s]; + break; + } } if (sumTopLevels > 0) { @@ -439,10 +458,18 @@ private void CalculateTopStats(List creatures) { if (c.levelsWild == null || c.flags.HasFlag(CreatureFlags.Placeholder)) continue; int sumCreatureLevels = 0; - for (int s = 0; s < usedAndConsideredStatsCount; s++) + foreach (var s in usedAndConsideredStatIndices) { - int si = usedAndConsideredStatIndices[s]; - sumCreatureLevels += c.levelsWild[si] > 0 ? c.levelsWild[si] : 0; + switch (statPreferences[s]) + { + case StatWeighting.StatValuePreference.Low: + if (c.levelsWild[s] >= 0) + sumCreatureLevels += highestLevels[s] - c.levelsWild[s]; + break; + case StatWeighting.StatValuePreference.High: + sumCreatureLevels += c.levelsWild[s] > 0 ? c.levelsWild[s] : 0; + break; + } } c.topness = (short)(1000 * sumCreatureLevels / sumTopLevels); } diff --git a/ARKBreedingStats/library/Creature.cs b/ARKBreedingStats/library/Creature.cs index 1e8d7647..b06215bb 100644 --- a/ARKBreedingStats/library/Creature.cs +++ b/ARKBreedingStats/library/Creature.cs @@ -419,6 +419,7 @@ public Creature Mother motherGuid = mother?.guid ?? Guid.Empty; } } + public Creature Father { get => father; diff --git a/ARKBreedingStats/library/DummyCreatures.cs b/ARKBreedingStats/library/DummyCreatures.cs index 52d7323c..ecae6f38 100644 --- a/ARKBreedingStats/library/DummyCreatures.cs +++ b/ARKBreedingStats/library/DummyCreatures.cs @@ -244,7 +244,7 @@ private static List BreedCreatures(Creature[] creatures, Species speci var allCreaturesArray = noGender ? allCreatures.ToArray() : null; var pairs = BreedingScore.CalculateBreedingScores(noGender ? allCreaturesArray : femalesMales[Sex.Female].ToArray(), noGender ? allCreaturesArray : femalesMales[Sex.Male].ToArray(), species, bestPossibleLevels, statWeights, bestLevels, - BreedingPlan.BreedingMode.TopStatsConservative, false, false, 0, ref filteredOutByMutationLimit); + BreedingScore.BreedingMode.TopStatsConservative, false, false, 0, ref filteredOutByMutationLimit); var pairsCount = Math.Min(usePairsPerGeneration, pairs.Count); for (int i = 0; i < pairsCount; i++) diff --git a/ARKBreedingStats/uiControls/StatWeighting.cs b/ARKBreedingStats/uiControls/StatWeighting.cs index b48e9a3f..089ac36e 100644 --- a/ARKBreedingStats/uiControls/StatWeighting.cs +++ b/ARKBreedingStats/uiControls/StatWeighting.cs @@ -392,8 +392,8 @@ private void SetState(byte state) public enum StatValuePreference { Indifferent, - High, - Low + Low, + High } /// @@ -402,8 +402,8 @@ public enum StatValuePreference public enum StatValueEvenOdd { Indifferent, - Even, - Odd + Odd, + Even } } }