public void setThresholds() { double das = dataAge.Sum(); dataAgeThreshold = NewtonMethod(IdleObjective, IdleDerivative, das, Math.Floor(IdleObjective(das) * 100) / 100, .0001); dataXpThreshold = (ulong)Math.Ceiling(NewtonMethod(ActiveObjective, ActiveDerivative, dataXp, Math.Floor(ActiveObjective(dataXp) * 100) / 100, .0001)); }
private Tuple <double, double> ChanceOfBeatingTargetAndExpectedPIfYouDo(int gwLevel, double targetPValue) { List <double> expectations = new List <double>(); StableSummer probabilities = new StableSummer(); // start with godly ranks with 0 pluses // (no reliable reports of godly ranks ever getting pluses) double prob; double leSkillEffect = Upgrade.bsUpgrades[(int)UpgradeID.BSSKILL & 127][a.bsLevel + NumBS].value; double heSkillEffect = 0.5 + leSkillEffect; double basePower = Upgrade.bsUpgrades[(int)UpgradeID.BSBASEPOWER & 127][a.bbLevel + NumBBP].value; int rank; for (rank = firstGodlyRank; rank < overallNumberRanks; rank++) { prob = rankprobsByGwlevel[gwLevel][rank]; double expectedPAt100 = basePower * rankBonuses[rank]; double expectedPAtLowEnd = expectedPAt100 * leSkillEffect; double expectedPAtHighEnd = expectedPAt100 * heSkillEffect; // no plus bonus multiplier, makes things easy if (targetPValue < expectedPAtLowEnd) { // whole thing contributes // don't have to adjust prob // CODE IS CURRENTLY EXACT expectations.Add(prob * ExpectationOfRange(expectedPAtLowEnd, expectedPAtHighEnd)); probabilities.Add(prob); } else if (targetPValue < expectedPAtHighEnd) { // not all of the range contributes, so we have to adjust prob prob *= (expectedPAtHighEnd - targetPValue) / (expectedPAtHighEnd - expectedPAtLowEnd); // SLIGHT APPROXIMATION: // we may lose a small bit of accuracy here since something smaller than targetValue might be rounded to it expectations.Add(prob * ExpectationOfRange(targetPValue, expectedPAtHighEnd)); probabilities.Add(prob); } } // now we can do it for the mortal ranks (which can get plusbonuses after rounding) double maxContributionThisRound; // outer loop over possible plusbonuses int numPluses = 0; var modifiedPlusProbs = plusprob.Select(x => x + (a.bsLevel + this.NumBX) * .01).ToArray(); var probReachingHere = Enumerable.Repeat(1.0, plusprob.Count()); do { var probStoppingHere = probReachingHere.Zip(modifiedPlusProbs, (prh, mpp) => prh * (1 - mpp)); double plusBonus = GetPlusBonus(numPluses); maxContributionThisRound = 0; // this could be LINQed with a subfunction, zipping rankprob[gwlevel] and probStoppingHere CustomSequenceOperators.TripleForEach(rankprobsByGwlevel[gwLevel], probStoppingHere, rankBonuses, (rp, psh, rb) => ChanceInternal(rp, psh, rb, leSkillEffect, plusBonus, targetPValue, ref maxContributionThisRound, expectations, probabilities)); numPluses++; // might be faster without LINQ? probReachingHere = probReachingHere.Zip(probStoppingHere, (prh, psh) => prh - psh); } while (maxContributionThisRound > 1e-10); // all possible ranks, all possible enchantments double chance = probabilities.Sum(); return(Tuple.Create(chance, StableSum(expectations) / chance)); }