public static void AddGuaranteedPips(this LeaderPipResult leaderPipResult, LeaderPipModifiers leaderPipModifiers) { AddGuaranteedPipsSingleCategory(() => leaderPipResult.Fire, x => leaderPipResult.Fire = x, leaderPipModifiers.BonusFire); AddGuaranteedPipsSingleCategory(() => leaderPipResult.Shock, x => leaderPipResult.Shock = x, leaderPipModifiers.BonusShock); AddGuaranteedPipsSingleCategory(() => leaderPipResult.Maneuver, x => leaderPipResult.Maneuver = x, leaderPipModifiers.BonusManeuver); AddGuaranteedPipsSingleCategory(() => leaderPipResult.Siege, x => leaderPipResult.Siege = x, leaderPipModifiers.BonusSiege); }
public async Task <LeaderPipResult> DistributePipsAsync(double averageBasePips, LeaderPipModifiers leaderPipModifiers = null) { var slaveTasks = new List <Task <LeaderPipResult> >(); for (int i = 0; i < DegreeOfParallelism; i++) { slaveTasks.Add(Task.Run(() => RunSimulation(IterationsPerSlave, averageBasePips, leaderPipModifiers))); } await Task.WhenAll(slaveTasks); var result = new LeaderPipResult(); foreach (var slaveResult in slaveTasks.Select(s => s.Result)) { result.Fire += slaveResult.Fire; result.Shock += slaveResult.Shock; result.Maneuver += slaveResult.Maneuver; result.Siege += slaveResult.Siege; } result.Fire = Math.Round(result.Fire / DegreeOfParallelism, RoundingDigits); result.Shock = Math.Round(result.Shock / DegreeOfParallelism, RoundingDigits); result.Maneuver = Math.Round(result.Maneuver / DegreeOfParallelism, RoundingDigits); result.Siege = Math.Round(result.Siege / DegreeOfParallelism, RoundingDigits); return(result); }
private static LeaderPipResult DistributePips(double averageBasePips, LeaderPipModifiers leaderPipModifiers) { double remainingPips = averageBasePips; var result = new LeaderPipResult(); while (remainingPips > 10) { remainingPips -= 4; result.Fire++; result.Shock++; result.Maneuver++; result.Siege++; } result.AddGuaranteedPips(leaderPipModifiers ?? new LeaderPipModifiers()); // The approximation here is that these percentages don't reflect pip overflow from maxed out categories result.Fire += Math.Round(0.3 * remainingPips, 2); result.Shock += Math.Round(0.3 * remainingPips, 2); result.Maneuver += Math.Round(0.3 * remainingPips, 2); result.Siege += Math.Round(0.1 * remainingPips, 2); result.Fire = result.Fire > LeaderConstants.MaxPipsInCategory ? LeaderConstants.MaxPipsInCategory : result.Fire; result.Shock = result.Shock > LeaderConstants.MaxPipsInCategory ? LeaderConstants.MaxPipsInCategory : result.Shock; result.Maneuver = result.Maneuver > LeaderConstants.MaxPipsInCategory ? LeaderConstants.MaxPipsInCategory : result.Maneuver; result.Siege = result.Siege > LeaderConstants.MaxPipsInCategory ? LeaderConstants.MaxPipsInCategory : result.Siege; return(result); }
private static LeaderPipResult DistributePipsSimulation(double averageBasePips, LeaderPipModifiers leaderPipModifiers, Random random) { double remainingPips = averageBasePips; var result = new LeaderPipResult(); while (remainingPips > 10) { remainingPips -= 4; result.Fire++; result.Shock++; result.Maneuver++; result.Siege++; } result.AddGuaranteedPips(leaderPipModifiers ?? new LeaderPipModifiers()); while (remainingPips > 0) { int which = random.Next(0, 10); double amount = remainingPips >= 1 ? 1 : remainingPips; if (which == 0 && result.Siege < LeaderConstants.MaxPipsInCategory) { result.Siege += amount; remainingPips -= amount; } else if (which < 4 && result.Shock < LeaderConstants.MaxPipsInCategory) { result.Shock += amount; remainingPips -= amount; } else if (which < 7 && result.Fire < LeaderConstants.MaxPipsInCategory) { result.Fire += amount; remainingPips -= amount; } else if (result.Maneuver < LeaderConstants.MaxPipsInCategory) { result.Maneuver += amount; remainingPips -= amount; } // else go back to generating new which } return(result); }
private static LeaderPipResult RunSimulation(int iterations, double averageBasePips, LeaderPipModifiers leaderPipModifiers = null) { var random = new Random(DateTime.UtcNow.Millisecond); var result = new LeaderPipResult(); for (int i = 0; i < iterations; i++) { LeaderPipResult iterationResult = DistributePipsSimulation(averageBasePips, leaderPipModifiers, random); result.Fire += iterationResult.Fire; result.Shock += iterationResult.Shock; result.Maneuver += iterationResult.Maneuver; result.Siege += iterationResult.Siege; } result.Fire = Math.Round(result.Fire / iterations, RoundingDigits); result.Shock = Math.Round(result.Shock / iterations, RoundingDigits); result.Maneuver = Math.Round(result.Maneuver / iterations, RoundingDigits); result.Siege = Math.Round(result.Siege / iterations, RoundingDigits); return(result); }