public StableSummer(StableSummer cloneFrom)
     : this()
 {
     if (cloneFrom != null)
     {
         partials.AddRange(cloneFrom.partials);
     }
 }
Esempio n. 2
0
 public WealthStatistics()
 {
     dataAge          = new StableSummer();
     dataAgeThreshold = NewtonMethod(IdleObjective, IdleDerivative, 0, 0.01, 0.0001) * 25920000;
     dataXp           = 0;
     dataXpThreshold  = (uint)(Math.Ceiling(NewtonMethod(ActiveObjective, ActiveDerivative, 0, 0.01, 0.0001) * 10800));
     Gold             = 0;
     Gems             = 0;
     CurrentP         = 20;
     HighestOre       = 0;
 }
Esempio n. 3
0
 public WealthStatistics(WealthStatistics w)
 {
     dataAge          = new StableSummer(w.dataAge);
     dataAgeThreshold = w.dataAgeThreshold;
     dataXp           = w.dataXp;
     dataXpThreshold  = w.dataXpThreshold;
     _currentP        = w.CurrentP;
     _highestOre      = w.HighestOre;
     _gems            = w.Gems;
     _gold            = w.Gold;
 }
Esempio n. 4
0
        private void ChanceInternal(double rankprob,
                                    double probStoppingHere,
                                    double rankBonus,
                                    double leSkillEffect,
                                    double plusBonus,
                                    double targetPValue,
                                    ref double maxContributionThisRound,
                                    List <double> expectations,
                                    StableSummer probabilities)
        {
            double prob = rankprob * probStoppingHere;
            // TODO: Properly handle the 2x rounding that happens
            // first, calculates basepower * rankbonus * quality
            double expectedPAt100NoPlusbonus     = BasePower(a.bbLevel + this.NumBBP) * rankBonus;
            double expectedPAtLowEndNoPlusbonus  = Math.Round(expectedPAt100NoPlusbonus * leSkillEffect);
            double expectedPAtHighEndNoPlusbonus = Math.Round(expectedPAt100NoPlusbonus * (0.5 + leSkillEffect));
            double expectedPAtHighEnd            = Math.Round(expectedPAtHighEndNoPlusbonus * plusBonus);

            if (expectedPAtHighEnd > targetPValue)
            {
                double expectedPAtLowEnd = Math.Round(expectedPAtLowEndNoPlusbonus * plusBonus);
                double value;
                if (expectedPAtLowEnd > targetPValue)
                {
                    // APPROXIMATION
                    value = SimpleExpectation(expectedPAtLowEnd, expectedPAtHighEnd);
                }
                else
                {
                    // APPROXIMATION
                    // only portion between targetPValue and expectedPAtHighEnd
                    value = SimpleExpectation(targetPValue, expectedPAtHighEnd);
                    prob  = prob * (expectedPAtHighEnd - targetPValue) / (expectedPAtHighEnd - expectedPAtLowEnd);
                }
                double contribution = prob * value;
                if (contribution > maxContributionThisRound)
                {
                    maxContributionThisRound = contribution;
                }
                expectations.Add(contribution);
                probabilities.Add(prob);
            }
        }
Esempio n. 5
0
        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));
        }