Esempio n. 1
0
 public UpgradeSimulationResult(WealthStatistics nw, UpgradeState nu, double nt)
 {
     // shallow copy
     this.w = nw;
     this.u = nu;
     this.timeSpent = nt;
 }
Esempio n. 2
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;
 }
 private static void PromptForCurrentWealth(WealthStatistics wealth)
 {
     Console.WriteLine("Enter current gems");
     wealth.Gems = ulong.Parse(Console.ReadLine());
     Console.WriteLine("Enter current idle multiplier x 100 (no decimal point)");
     wealth.dataAge = ulong.Parse(Console.ReadLine());
     Console.WriteLine("Enter current active multiplier x 100 (no decimal point)");
     wealth.dataXp = ulong.Parse(Console.ReadLine());
     Console.WriteLine("Enter current gold");
     wealth.Gold = double.Parse(Console.ReadLine());
 }
        static void Main(string[] args)
        {
            UpgradeState     ua     = new UpgradeState();
            WealthStatistics wealth = new WealthStatistics();

            PromptForCurrentStatistics(ua, wealth);
            var x = new IdleMineOptimizer(ua, wealth);

            x.Calc();
            OutputUpgradePath(x.OptimalUpgradePath);
            OutputShoppingCart(x.OptimalShoppingCart);
        }
Esempio n. 5
0
        public static int ComputeMostLucrativeOre(int[] upgradeState, WealthStatistics currentStatistics, out uint clicksForEachVictory, out double valueOfEachVictory)
        {
            double rawPickDamage          = currentStatistics.CurrentP * currentStatistics.IdleActiveMultipliers() * upgradeState[(int)UpgradeID.ICAUTOPOWER & 127];
            Ore    fakeOreForComparingRpd = new Ore()
            {
                Defense = 0, Hp = rawPickDamage, MinHpcToConsider = rawPickDamage, MaxHpcToConsider = rawPickDamage
            };
            int lowestFeasibleOre = Ore.oreList.BinarySearch(0, currentStatistics.HighestOre + 7,
                                                             fakeOreForComparingRpd, new MinDamageComparer());
            int highestFeasibleOre = Ore.oreList.BinarySearch(lowestFeasibleOre, currentStatistics.HighestOre + 7 - lowestFeasibleOre,
                                                              fakeOreForComparingRpd, new MaxDamageComparer());

            if (lowestFeasibleOre < 0)
            {
                lowestFeasibleOre = ~lowestFeasibleOre - 1;
            }
            if (highestFeasibleOre < 0)
            {
                highestFeasibleOre = ~highestFeasibleOre;
            }
            int oreIndexMaxRevenue = highestFeasibleOre;
            Ore oreAtMaxRevenue    = Ore.oreList[oreIndexMaxRevenue];

            oreAtMaxRevenue.UpdateClicks(rawPickDamage);
            //double maxRevenuePerClick = oreAtMaxRevenue.ValuePerClick;
            for (int i = lowestFeasibleOre; i < highestFeasibleOre; i++)
            {
                Ore temp = Ore.oreList[i];
                temp.UpdateClicks(rawPickDamage);
                if (temp.ValuePerClick > oreAtMaxRevenue.ValuePerClick)
                {
                    oreAtMaxRevenue    = temp;
                    oreIndexMaxRevenue = i;
                }
            }
            if (currentStatistics.HighestOre < oreIndexMaxRevenue)
            {
                oreIndexMaxRevenue = currentStatistics.HighestOre;
            }
            clicksForEachVictory = Ore.oreList[oreIndexMaxRevenue].Clicks;
            valueOfEachVictory   = Ore.oreList[oreIndexMaxRevenue].Value;
            return(oreIndexMaxRevenue);
        }
Esempio n. 6
0
 public IdleMineOptimizer(UpgradeState ua, WealthStatistics inst)
 {
     initialUpgradeState = ua;
     initialStats = inst;
 }
Esempio n. 7
0
        public void Calc()
        {
            double bestEfficiency = 0;
            ShoppingCart cartForBestEfficiency = null;
            ClickUpgradePath pathForBestEfficiency = null;
            int gwForBestEfficiency = -1;

            var pathCollection = AllReasonableUpgradePaths();
            var cartCollection = AllReasonableShoppingCarts();
            var pCollection = GetPCollection(); // collection of P values to shoot for

            foreach (var upgradePath in pathCollection)
            {
                IList<ClickUpgradePath.UpgradeSimulationResult> pathSimulationGroup = upgradePath.Simulate(initialStats);
                foreach (ClickUpgradePath.UpgradeSimulationResult pathSimulation in pathSimulationGroup)
                {
                    WealthStatistics pathResult = pathSimulation.w;
                    UpgradeState completedInstantUpgrades = pathSimulation.u;
                    double timeSpent = pathSimulation.timeSpent;
                
                double clicksPerSecond = Upgrade.ic(UpgradeID.ICAUTOSPEED)[completedInstantUpgrades.afLevel].value;
                double gemFinderOdds = Upgrade.ic(UpgradeID.ICGEMFINDER)[completedInstantUpgrades.gfLevel].value;
                double autoPowerMultiplier = Upgrade.ic(UpgradeID.ICAUTOPOWER)[completedInstantUpgrades.apLevel].value;
                foreach (var sc in cartCollection)
                {
                    var costs = sc.TotalCostWithoutAndWithGemwaster();
                    //double timeSpentBuyingBSUpgradesOnceWeHaveEnoughMoney = (sc.NumBBP + sc.NumBF + sc.NumBS + sc.NumBX)/6.5 + (sc.NumBBP>0 ? 1 : 0) + (sc.NumBF<0 ? 1 : 0) + (sc.NumBS>0?1:0)+(sc.NumBX>0?1:0);
                    double efficiencyDiscount = 0.01 * (100 - completedInstantUpgrades.bfLevel - sc.NumBF);
                    foreach (var desiredP in pCollection)
                    {
                        int gw = 0;

                        foreach(var expect in sc.ChancesOfBeatingTargetAndExpectedPsIfYouDo(desiredP)) // each item corresponds to a different gemwaster
                        {
                            double costOfShoppingCart = (gw <= this.initialUpgradeState.gwLevel) ? costs.Item1 : costs.Item2;
                            double averageGemsForOneCraft = ShoppingCart.gwNumberOfGems[gw] * efficiencyDiscount;
                            double failChance = 1-expect.Item1;
                            // need to solve failChance^expectedNumCrafts < .2
                            // n ln failchance < ln .2
                            // n = ln .2 / ln failchance
                            double expectedNumCrafts = lnConfidenceLevel/Math.Log(failChance);
                            double expectedCraftingTime = expectedNumCrafts / 6.5;
                            double gemsRequired = expectedNumCrafts * averageGemsForOneCraft - pathResult.Gems; // still exact
                            // due to linearity of expectation
                            double expectedNeededOresMined = Math.Ceiling(gemsRequired / gemFinderOdds);
                            double hpc = pathResult.IdleActiveMultipliers()*pathResult.CurrentP*autoPowerMultiplier;
                            var miningList = EarnMoney.MiningPlanToEarnSpecifiedGoldAndGems(hpc, costOfShoppingCart, expectedNeededOresMined);
                            double timeSavingUpGoldAndGemsForCraft = miningList.Sum(x => x.Item2 * x.Item1.Clicks)*Upgrade.ic(UpgradeID.ICAUTOSPEED)[completedInstantUpgrades.afLevel].value;
                            double totalTime = timeSpentFollowingUpgradePath
                                + timeSavingUpGoldAndGemsForCraft
                                //+ timeSpentBuyingBSUpgradesOnceWeHaveEnoughMoney // can buy them on-the-run
                                + expectedCraftingTime;
                            pathResult.CurrentP = expect.Item2;
                            int clicksForEachVictory;
                            double valueOfEachVictory;
                            var stats = Ore.OptimalOreForCash( ); completedInstantUpgrades.instant, pathResult, out clicksForEachVictory, out valueOfEachVictory);

                            gw++;
                        }
                    }
                    
                    
                    
                }
                
            }

        }

    }
Esempio n. 8
0
        internal void Simulate(WealthStatistics initialStats,
            UpgradeState upgradesWithoutGemfinder,
            UpgradeState upgradesWithGemfinder,
            WealthStatistics wealthWithoutGemfinder,
            IList<WealthStatistics> wealthWithGemfinderBoughtAfterIthUpgrade)
        {
            var retval = new UpgradeSimulationResult[UpgradeOrder.Count + 1];
            List<WealthStatistics> currentStatistics = { new WealthStatistics(initialStats) };
            UpgradeState usWithoutGemfinder = new UpgradeState(us);
            UpgradeState usWithGemfinder;
            bool gfMaxed = usWithoutGemfinder.gfLevel == Upgrade.ic(UpgradeID.ICGEMFINDER).Count - 1;
            int itemsBoughtSoFar = 0;
            double secondsPerClick = 1/Upgrade.ic(UpgradeID.ICAUTOSPEED)[usWithoutGemfinder.afLevel].value;
            double gemsForEachVictoryBefore = Upgrade.ic(UpgradeID.ICGEMFINDER)[usWithoutGemfinder.gfLevel].value;
            double gemsForEachVictoryAfter = gfMaxed ? 0 : Upgrade.ic(UpgradeID.ICGEMFINDER)[usWithoutGemfinder.gfLevel + 1].value;
            int ore = -1;
            uint clicksForEachVictory=0;
            double timeForEachVictory = 0;
            double valueOfEachVictory=0;
            while (itemsBoughtSoFar < UpgradeOrder.Count)
            {
                UpgradeID pendingItem = _upgradeOrder[itemsBoughtSoFar];
                int upgradeLevelOfPendingItem = usWithoutGemfinder.instant[(int)pendingItem&127];

                Upgrade nextUpgrade = Upgrade.ic(pendingItem)[upgradeLevelOfPendingItem];
                double nextLevelCost = nextUpgrade.nextLevelCost;
                foreach (
                while (currentStatistics.Any(x=>x.Gold < nextLevelCost))
                {
                    if (ore == -1)
                    {
                        RecomputeOre(x, usWithoutGemfinder, secondsPerClick, out clicksForEachVictory, out valueOfEachVictory, out ore, out timeForEachVictory);
                    } 
                    currentStatistics.ForEach(x=>
                    {
                        x.Gold += valueOfEachVictory;
                        x.Gems += something ? gemsForEachVictoryBefore : gemsForEachVictoryAfter;
                        x.dataXp += clicksForEachVictory;
                        x.dataAge.Add(timeForEachVictory);
                    timeSpent += timeForEachVictory;
                    if (currentStatistics.dataXp > currentStatistics.dataXpThreshold || currentStatistics.dataAge.Sum() > currentStatistics.dataAgeThreshold)
                    {
                        currentStatistics.setThresholds();
                        ore = -1; // or recompute now
                    }
                    if (ore == currentStatistics.HighestOre)
                    {
                        currentStatistics.HighestOre++;
                        ore = -1; // or recompute now
                    }
                    if (ore == -1 && currentStatistics.Gold < nextLevelCost)
                    {
                        RecomputeOre(currentStatistics, usWithoutGemfinder, secondsPerClick, out clicksForEachVictory, out valueOfEachVictory, out ore, out timeForEachVictory);
                    }
                }

                // TODO: Handle this with a dictionary or list of delegates
                switch (pendingItem)
                {
                    case UpgradeID.ICAUTOSPEED:
                        usWithoutGemfinder.afLevel++;
                        secondsPerClick = Upgrade.ic(UpgradeID.ICAUTOSPEED)[usWithoutGemfinder.afLevel].value;
                        timeForEachVictory = clicksForEachVictory * secondsPerClick;
                        break;
                    case UpgradeID.ICAUTOPOWER:
                        usWithoutGemfinder.apLevel++;
                        ore = Ore.ComputeMostLucrativeOre(usWithoutGemfinder.instant, currentStatistics, out clicksForEachVictory, out valueOfEachVictory);
                        timeForEachVictory = clicksForEachVictory * secondsPerClick;
                        break;
                    case UpgradeID.ICGEMFINDER:
                        usWithoutGemfinder.gfLevel++;
                        gemsForEachVictoryBefore = Upgrade.ic(UpgradeID.ICGEMFINDER)[usWithoutGemfinder.gfLevel].value;
                        break;
                }
                currentStatistics.Gold -= nextLevelCost;
                timeSpent += 1.0; // it takes some time to click
                itemsBoughtSoFar++;
            }
            foreach (UpgradeSimulationResult thing in retval)
            {
                thing.u = usWithGemfinder;
            }
            retval[retval.Length()-1].u = usWithoutGemfinder;
            retval[retval.Length()-1].w = currentStatistics;
            return Tuple.Create(currentStatistics,usWithoutGemfinder);
        }
Esempio n. 9
0
 private static void RecomputeOre(WealthStatistics currentStatistics, UpgradeState currentUpgradeState, double secondsPerClick, out uint clicksForEachVictory, out double valueOfEachVictory, out int ore, out double timeForEachVictory)
 {
     ore = Ore.ComputeMostLucrativeOre(currentUpgradeState.instant, currentStatistics, out clicksForEachVictory, out valueOfEachVictory);
     timeForEachVictory = VictorySeconds(secondsPerClick, clicksForEachVictory);
 }
 static void PromptForCurrentStatistics(UpgradeState ua, WealthStatistics wealth)
 {
     PromptForCurrentUpgradeState(ua);
     PromptForCurrentWealth(wealth);
 }