private void Calculate_Click(object sender, RoutedEventArgs e) { if (castingState == null || generator == null) { return; } string name = generator.ConvertCycleNameEasyToInternal(ControlString.Text); if (name.Length != generator.ControlOptions.Length) return; for (int i = 0; i < generator.ControlOptions.Length; i++) { generator.ControlValue[i] = int.Parse(name[i].ToString()); } try { GenericCycle generic = new GenericCycle(name, castingState, generator.StateList, true); StringBuilder sb = new StringBuilder(); sb.AppendLine(generic.DamagePerSecond + " Dps"); sb.AppendLine(generic.ManaPerSecond + " Mps"); sb.AppendLine(generic.ThreatPerSecond + " Tps"); sb.AppendLine(generic.DpsPerSpellPower + " Dps per Spell Power"); sb.AppendLine(generic.DpsPerMastery + " Dps per Mastery"); sb.AppendLine((generic.DpsPerCrit / 100) + " Dps per Crit"); sb.AppendLine((generic.CastProcs / generic.CastTime) + " Cast Procs / Sec"); sb.AppendLine((generic.HitProcs / generic.CastTime) + " Hit Procs / Sec"); sb.AppendLine((generic.CritProcs / generic.CastTime) + " Crit Procs / Sec"); sb.AppendLine((generic.DamageProcs / generic.CastTime) + " Damage Procs / Sec"); sb.AppendLine((generic.DotProcs / generic.CastTime) + " Dot Procs / Sec"); sb.AppendLine(); sb.AppendLine(generic.SpellDistribution); Result.Text = sb.ToString(); } catch (OutOfMemoryException /*ex*/) { Result.Text = "State Space too complex to solve, please select a different cycle solver."; } }
private void HotStreakUtilization_Click(object sender, RoutedEventArgs e) { string armor = "Molten Armor"; CalculationOptionsMage calculationOptions = Character.CalculationOptions as CalculationOptionsMage; CalculationsMage calculations = (CalculationsMage)Calculations.Instance; Solver solver = new Solver(Character, calculationOptions, false, false, false, 0, armor, false, false, true, false, true, false, false); solver.Initialize(null); CastingState baseState = new CastingState(solver, 0, false, 0); FireCycleGenerator generator = new FireCycleGenerator(baseState); GenericCycle c1 = new GenericCycle("test", baseState, generator.StateList, true); Cycle c2 = baseState.GetCycle(CycleId.FBLBPyro); Dictionary<string, SpellContribution> dict1 = new Dictionary<string, SpellContribution>(); Dictionary<string, SpellContribution> dict2 = new Dictionary<string, SpellContribution>(); c1.AddDamageContribution(dict1, 1.0f, 0); c2.AddDamageContribution(dict2, 1.0f, 0); float predicted = dict2["Pyroblast"].Hits / dict2["Fireball"].Hits; float actual = dict1["Pyroblast"].Hits / dict1["Fireball"].Hits; StringBuilder sb = new StringBuilder(); sb.AppendLine("Pyro/Nuke Ratio:"); sb.AppendLine(); sb.AppendLine("Approximation Model: " + predicted); sb.AppendLine("Exact Model: " + actual); sb.AppendLine(); // predicted = raw * (1 - wastedold) // actual = raw * (1 - wasted) // wasted = 1 - actual / predicted * (1 - wastedold) sb.AppendLine("Predicted Wasted Hot Streaks: " + (1 - actual / predicted)); MessageBox.Show(sb.ToString()); }
public List<Cycle> Analyze(CastingState castingState, Cycle wand, System.ComponentModel.BackgroundWorker worker) { Dictionary<string, Cycle> cycleDict = new Dictionary<string, Cycle>(); int j; // reset for (int i = 0; i < ControlValue.Length; i++) { ControlValue[i] = 0; } // count total cycles int total = 0; do { total++; j = ControlValue.Length - 1; ControlValue[j]++; while (ControlValue[j] >= ControlOptions[j]) { ControlValue[j] = 0; j--; if (j < 0) { break; } ControlValue[j]++; } } while (j >= 0); // reset for (int i = 0; i < ControlValue.Length; i++) { ControlValue[i] = 0; } int count = 0; do { if (worker != null && worker.CancellationPending) { break; } if (worker != null && count % 100 == 0) { worker.ReportProgress((100 * count) / total, count + "/" + total); } count++; string name = ""; for (int i = 0; i < ControlValue.Length; i++) { name += ControlValue[i].ToString(); } GenericCycle generic = new GenericCycle(name, castingState, StateList, false); if (!cycleDict.ContainsKey(generic.SpellDistribution)) { cycleDict.Add(generic.SpellDistribution, generic); } // increment control j = ControlValue.Length - 1; ControlValue[j]++; while (ControlValue[j] >= ControlOptions[j]) { ControlValue[j] = 0; j--; if (j < 0) { break; } ControlValue[j]++; } } while (j >= 0); if (wand != null) { cycleDict["Wand"] = wand; } List<Cycle> cyclePalette = new List<Cycle>(); double maxdps = 0; Cycle maxdpsCycle = null; foreach (Cycle cycle in cycleDict.Values) { if (cycle.DamagePerSecond > maxdps) { maxdpsCycle = cycle; maxdps = cycle.DamagePerSecond; } } cyclePalette.Add(maxdpsCycle); Cycle mindpmCycle; do { Cycle highdpsCycle = cyclePalette[cyclePalette.Count - 1]; RESTART: mindpmCycle = null; double mindpm = double.PositiveInfinity; foreach (Cycle cycle in cycleDict.Values) { double dpm = (cycle.DamagePerSecond - highdpsCycle.DamagePerSecond) / (cycle.ManaPerSecond - highdpsCycle.ManaPerSecond); if (dpm > 0 && dpm < mindpm && cycle.ManaPerSecond < highdpsCycle.ManaPerSecond) { mindpm = dpm; mindpmCycle = cycle; } } if (mindpmCycle != null) { // validate cycle pair theory foreach (Cycle cycle in cycleDict.Values) { double dpm = (cycle.DamagePerSecond - mindpmCycle.DamagePerSecond) / (cycle.ManaPerSecond - mindpmCycle.ManaPerSecond); if (cycle != highdpsCycle && cycle.DamagePerSecond > mindpmCycle.DamagePerSecond && dpm > mindpm + 0.000001) { highdpsCycle = cycle; goto RESTART; } } cyclePalette.Add(mindpmCycle); } } while (mindpmCycle != null); return cyclePalette; }