public static int OptimalOreForCash(double hpc, ref int searchStartpoint) { Ore fakeOreForBinarySearch = new Ore("", hpc, 0, 0, hpc, hpc, 0); int maxOreIndex = oreList.BinarySearch(searchStartpoint, oreList.Count - searchStartpoint, fakeOreForBinarySearch, new MinDamageComparer()); if (maxOreIndex > 0) { Ore o = oreList[maxOreIndex]; if (o.MinHpcToConsider != o.MaxHpcToConsider) { // exactly hit a good ore at its minimum value oreList[maxOreIndex].UpdateClicks(hpc); return(maxOreIndex); } maxOreIndex--; // exactly hit a dud ore } else { // a negative return value means the ~ of the place where this value would be inserted maxOreIndex = ~maxOreIndex - 1; } Ore optimalOreSoFar = fakeOreForBinarySearch; int optimalIndex = -1; for (int candidateIndex = maxOreIndex; candidateIndex >= 0; candidateIndex--) { Ore candidateOre = oreList[candidateIndex]; if (hpc < candidateOre.MaxHpcToConsider) { candidateOre.UpdateClicks(hpc); if (candidateOre.ValuePerClick > optimalOreSoFar.ValuePerClick) { optimalOreSoFar = candidateOre; optimalIndex = candidateIndex; } } if (hpc >= candidateOre.MaxHpcOfAllAbove) // past last possible point { searchStartpoint = candidateIndex; break; } } return(optimalIndex); }
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); }