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); }
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++; } } } } } }