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); }
public IdleMineOptimizer(UpgradeState ua, WealthStatistics inst) { initialUpgradeState = ua; initialStats = inst; }
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++; } } } } } }
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); }
public ClickUpgradePath(ClickUpgradePath x) { _upgradeOrder = new List<UpgradeID>(); _upgradeOrder.AddRange(x._upgradeOrder); // deep copy us = x.us; // shallow is okay }
public ClickUpgradePath(UpgradeState us) { _upgradeOrder = new List<UpgradeID>(); efficiency = 0; this.us = us; }
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); }