private static void PromptForCurrentUpgradeState(UpgradeState ua)
        {
BBP:
            Console.WriteLine("Enter blacksmith base power level, 0 for no upgrades, must be nonnegative");
            if (!int.TryParse(Console.ReadLine(), out ua.blacksmith[0]))
            {
                goto BBP;
            }
            // optionally show actual level/price from array
            uint state = 1;

            do
            {
                state = TransitionFunction(state, ua);
                if (state == 0)
                {
                    goto BBP;
                }
            } while (state < 8);
        }
        private static uint TransitionFunction(uint currentState, UpgradeState ua)
        {
            StateMachine s = m[currentState];

            Console.WriteLine("Enter {0}, 0 for no upgrades, max {1}, negative to go back",
                              s.prompt,
                              s.max);
            int temp;

            if (!int.TryParse(Console.ReadLine(), out temp) || temp > s.max)
            {
                return(currentState);
            }
            if (temp < 0)
            {
                return(currentState - 1);
            }
            ua.blacksmith[currentState] = temp;
            if (s.f != null)
            {
                s.f.Invoke((uint)temp);
            }
            return(currentState + 1);
        }
示例#3
0
 public IdleMineOptimizer(UpgradeState ua, WealthStatistics inst)
 {
     initialUpgradeState = ua;
     initialStats = inst;
 }
示例#4
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++;
                        }
                    }
                    
                    
                    
                }
                
            }

        }

    }
示例#5
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);
        }
示例#6
0
 public ClickUpgradePath(ClickUpgradePath x)
 {
     _upgradeOrder = new List<UpgradeID>();
     _upgradeOrder.AddRange(x._upgradeOrder); // deep copy
     us = x.us; // shallow is okay
 }
示例#7
0
 public ClickUpgradePath(UpgradeState us)
 {
     _upgradeOrder = new List<UpgradeID>();
     efficiency = 0;
     this.us = us;
 }
示例#8
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);
 }
 public UpgradeState(UpgradeState us)
 {
     us.blacksmith.CopyTo(blacksmith, 0);
     us.instant.CopyTo(instant, 0);
 }