public void StateSpaceGeneratorArmsTest1(Character c, Stats s, CombatFactors cf, Skills.WhiteAttacks wa, CalculationOptionsDPSWarr co, BossOptions bo) { ArmsGenerator gen = new ArmsGenerator(c, s, cf, wa, co, bo); var stateSpace = gen.GenerateStateSpace(); string output = ""; foreach (State <Rawr.DPSWarr.Skills.Ability> a in stateSpace) { output += a.ToString() + "\n"; } output += "\ndone"; try { MarkovProcess <Skills.Ability> mp = new MarkovProcess <Skills.Ability>(stateSpace); double averageDamage = 0.0; foreach (KeyValuePair <Skills.Ability, double> kvp in mp.AbilityWeight) { averageDamage += kvp.Key.DamageOnUse * kvp.Value; } double dps = averageDamage / mp.AverageTransitionDuration; dps += gen.Rot.WhiteAtks.MhDPS; } catch (Exception ex) { new ErrorBox("Error in creating Arms Markov Calculations", ex.Message, "StateSpaceGeneratorArmsTest1()", "StateSpace Count: " + stateSpace.Count.ToString(), ex.StackTrace); } }
private void Compile(List <Token.Token> tokens) { // determine first image id foreach (var token in tokens) { if (token is ImageToken itoken) { firstImageId = itoken.Id; break; } } // determine final token tokens = MarkovProcess.Run(GetRules(), tokens); if (tokens.Count != 1) { throw new Exception("Could not resolve all tokens to an expression"); } if (tokens[0].TokenType != Token.Token.Type.Value) { throw new Exception("Please enter a valid formula"); } finalToken = (ValueToken)tokens[0]; }
public void MarkovProcessTest3() { //S0: //AB-ABar1 => S0 0.8 * 0.8 // => S1 1 - 0.8 * 0.8 //S1: //MBAM-ABar => S0 0.8 // => S1 0.2 Ability AB = new Ability(); Ability ABar1 = new Ability(); Ability MBAM = new Ability(); Ability ABar = new Ability(); Ability ABABar1 = new AbilitySequence(AB, ABar1); Ability MBAMABar = new AbilitySequence(MBAM, ABar); State <Ability> S0 = new State <Ability>() { Name = "S0" }; State <Ability> S1 = new State <Ability>() { Name = "S1" }; S0.Transitions = new List <StateTransition <Ability> >() { new StateTransition <Ability>() { Ability = ABABar1, TargetState = S0, TransitionDuration = ABABar1.Duration, TransitionProbability = 0.8 * 0.8 }, new StateTransition <Ability>() { Ability = ABABar1, TargetState = S1, TransitionDuration = ABABar1.Duration, TransitionProbability = 1.0 - 0.8 * 0.8 }, }; S1.Transitions = new List <StateTransition <Ability> >() { new StateTransition <Ability>() { Ability = MBAMABar, TargetState = S0, TransitionDuration = MBAMABar.Duration, TransitionProbability = 0.8 }, new StateTransition <Ability>() { Ability = MBAMABar, TargetState = S1, TransitionDuration = MBAMABar.Duration, TransitionProbability = 0.2 }, }; List <State <Ability> > stateSpace = new List <State <Ability> >() { S0, S1 }; MarkovProcess <Ability> mp = new MarkovProcess <Ability>(stateSpace); Assert.AreEqual(mp.StateWeight[0], 0.69, 0.01, "S0"); Assert.AreEqual(mp.StateWeight[1], 0.31, 0.01, "S1"); }
public virtual void doIterations() { if (this.Char.Ranged == null) { return; } HunterStateSpaceGenerator HSSG; MarkovProcess <AbilWrapper> mp; // For starters lets build up what the rotation would look like for a given Spec: #region BM if ((TalentTrees)Talents.HighestTree == TalentTrees.BeastMastery) { // Normal Rotation: // Focus Fire when it’s ready // Kill Shot (if available) // Kill Command // Arcane Shot // Cobra Shot } #endregion #region MM else if ((TalentTrees)Talents.HighestTree == TalentTrees.Marksmanship) { HSSG = new HunterStateSpaceGenerator(Talents, Fight); // Setup State Space. HSSG.AbilityList = AbilityList; List <State <AbilWrapper> > SSpace = HSSG.GenerateStateSpace(); mp = new MarkovProcess <AbilWrapper>(SSpace); // Generate weightings for each ability. foreach (KeyValuePair <AbilWrapper, double> kvp in mp.AbilityWeight) { kvp.Key.AbilityWeight = kvp.Value; kvp.Key.DPS = kvp.Key.Damage / (float)mp.AverageTransitionDuration; } } #endregion #region SV else if ((TalentTrees)Talents.HighestTree == TalentTrees.Marksmanship) { // Normal Rotation: // Explosive Shot // Kill Shot (if available) // Black Arrow // Arcane Shot // Cobra Shot // Lock & Load Rotation: // Explosive Shot // Cobra Shot (or Kill Command if you’re almost full on focus) // Explosive Shot // Cobra Shot (or Arcane Shot if you know you have plenty of focus for the next Black Arrow) // Explosive Shot } #endregion }
public void MarkovProcessTest2() { //S0: //A => S0 0.5 //AB => S0 0.5 Ability A = new Ability() { Damage = 100, Duration = 2 }; Ability B = new Ability() { Damage = 200, Duration = 1 }; Ability AB = new AbilitySequence(A, B); State <Ability> S0 = new State <Ability>() { Name = "S0" }; S0.Transitions = new List <StateTransition <Ability> >() { new StateTransition <Ability>() { Ability = A, TargetState = S0, TransitionDuration = A.Duration, TransitionProbability = 0.5 }, new StateTransition <Ability>() { Ability = AB, TargetState = S0, TransitionDuration = AB.Duration, TransitionProbability = 0.5 }, }; List <State <Ability> > stateSpace = new List <State <Ability> >() { S0 }; MarkovProcess <Ability> mp = new MarkovProcess <Ability>(stateSpace); Assert.AreEqual(mp.StateWeight[0], 1.0, 0.000000000001, "S0"); Assert.AreEqual(mp.AverageTransitionDuration, 2.5, 0.000000000001, "time"); double averageDamage = 0.0; foreach (KeyValuePair <Ability, double> kvp in mp.AbilityWeight) { averageDamage += kvp.Key.Damage * kvp.Value; } Assert.AreEqual(averageDamage, 200.0, "damage"); Assert.AreEqual(averageDamage / mp.AverageTransitionDuration, 80.0, 0.000000000001, "dps"); }
public double[] GenerateCycle() { _process = new MarkovProcess <MoonkinCycleAbility>(_generator.GenerateStateSpace()); double[] retval = new double[8]; foreach (KeyValuePair <MoonkinCycleAbility, double> kvp in _process.AbilityWeight) { int idx = Array.IndexOf(MoonkinSolver.CastDistributionSpells, kvp.Key.Name); retval[idx] = kvp.Value; } return(retval); }
public void StateSpaceGeneratorTest1() { AB3ABarGenerator gen = new AB3ABarGenerator(); var stateSpace = gen.GenerateStateSpace(); MarkovProcess <Ability> mp = new MarkovProcess <Ability>(stateSpace); double unit = mp.AbilityWeight[gen.AB0]; Assert.AreEqual(mp.AbilityWeight[gen.AB0] / unit, 1.0, 0.000001, "AB0"); Assert.AreEqual(mp.AbilityWeight[gen.AB1] / unit, 1.0, 0.000001, "AB1"); Assert.AreEqual(mp.AbilityWeight[gen.AB2] / unit, 0.8, 0.000001, "AB2"); Assert.AreEqual(mp.AbilityWeight[gen.ABar] / unit, 0.36, 0.000001, "ABar"); Assert.AreEqual(mp.AbilityWeight[gen.ABar3] / unit, 0.64, 0.000001, "ABar3"); Assert.AreEqual(mp.AbilityWeight[gen.MBAM2] / unit, 0.2, 0.000001, "MBAM2"); Assert.AreEqual(mp.AbilityWeight[gen.MBAM3] / unit, 0.16, 0.000001, "MBAM3"); Assert.AreEqual(mp.AbilityWeight[gen.MBAM] / unit, 0.3024, 0.000001, "MBAM"); }
internal CharacterCalculationsBase GetCharacterCalculations(Character character) { CharacterCalculationsRestoSham calcs = new CharacterCalculationsRestoSham() { BasicStats = _TotalStats.Clone(), BurstSequence = _CalculationOptions.BurstStyle, SustainedSequence = _CalculationOptions.SustStyle, MailSpecialization = (GetArmorSpecializationStatus(character) ? 0.05f : 0f) }; float healingCriticalScale = 1.5f * (1 + _TotalStats.BonusCritHealMultiplier); float dmgCriticalScale = 2f * (1 + _TotalStats.BonusCritDamageMultiplier); float hasteScale = 1f / (1f + _TotalStats.SpellHaste); calcs.SustainedHPS = 0f; calcs.BurstHPS = 0f; foreach (HealingSpell spell in _AvailableSpells.OfType<HealingSpell>()) { spell.EffectModifier *= (1 + _TotalStats.BonusHealingDoneMultiplier); spell.CriticalScale = healingCriticalScale; spell.HasteScale = hasteScale; spell.Latency = _Latency; spell.GcdLatency = _GcdLatency; spell.SpellPower = _TotalStats.SpellPower; spell.CritRate = _TotalStats.SpellCrit; spell.Calculate(); calcs.SustainedHPS += spell.EPS; if (spell is EarthShield) calcs.ESHPS = spell.EPS; } foreach (LightningBolt spell in _AvailableSpells.OfType<LightningBolt>()) { spell.EffectModifier *= (1 + _TotalStats.BonusDamageMultiplier); spell.CriticalScale = dmgCriticalScale; spell.HasteScale = hasteScale; spell.Latency = _Latency; spell.GcdLatency = _GcdLatency; spell.SpellPower = _TotalStats.SpellPower; spell.CritRate = _TotalStats.SpellCrit; spell.Calculate(); calcs.LBRestore = spell.ManaBack - spell.ManaCost; calcs.LBCast = spell.CastTime; } float mp5 = _TotalStats.Mp5 + (_TotalStats.ManaRestoreFromMaxManaPerSecond * _TotalStats.Mana); if (_PerformSequencing) { { StateMachine.StateGenerator gen = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Burst, _TotalStats.Mana, mp5); List<State<Spell>> stateSpace = gen.GenerateStateSpace(); MarkovProcess<Spell> mp = new MarkovProcess<Spell>(stateSpace); _BurstSpellSequence = new Dictionary<Spell, double>(mp.AbilityWeight); _BurstSequenceDuration = mp.AverageTransitionDuration; } { StateMachine.StateGenerator gen = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Sustained, _TotalStats.Mana, mp5); List<State<Spell>> stateSpace = gen.GenerateStateSpace(); MarkovProcess<Spell> mp = new MarkovProcess<Spell>(stateSpace); _SustSpellSequence = new Dictionary<Spell, double>(mp.AbilityWeight); _SustSequenceDuration = mp.AverageTransitionDuration; } if (_PerformSequencing) _SequencedStats = _TotalStats.Clone(); } if (_BurstSpellSequence != null) { double avgHealing = 0d; string seq = ""; string seqShort = ""; foreach (var item in _BurstSpellSequence) { if (item.Key is HealingSpell) { if (seq.Length > 0) { seqShort += ","; seq += ", "; } seqShort += item.Key.SpellAbrv; seq += item.Key.SpellName; avgHealing += item.Key.Effect * item.Value; if (item.Key is Hot) avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value; } } double hps = avgHealing / _BurstSequenceDuration; calcs.BurstHPS = (float)hps; calcs.BurstSequence = seq; calcs.BurstSequenceShort = seqShort; } if (_SustSpellSequence != null) { double avgHealing = 0d; string seq = ""; string seqShort = ""; foreach (var item in _SustSpellSequence) { if (item.Key is HealingSpell) { if (seq.Length > 0) { seqShort += ","; seq += ", "; } seqShort += item.Key.SpellAbrv; seq += item.Key.SpellName; avgHealing += item.Key.Effect * item.Value; if (item.Key is Hot) avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value; } } double hps = avgHealing / _SustSequenceDuration; calcs.SustainedHPS = (float)hps; calcs.SustainedSequence = seq; calcs.SustainedSequenceShort = seqShort; } if (calcs.BurstHPS < 0f) calcs.BurstHPS = 0f; if (calcs.SustainedHPS < 0f) calcs.SustainedHPS = 0f; if (calcs.Survival < 0f) calcs.Survival = 0f; calcs.Survival = (calcs.BasicStats.Health + calcs.BasicStats.Hp5) * (_CalculationOptions.SurvivalPerc * .01f); // Set the sub categories calcs.SubPoints[0] = calcs.BurstHPS; calcs.SubPoints[1] = calcs.SustainedHPS; calcs.SubPoints[2] = calcs.Survival; // Sum up calcs.OverallPoints = 0f; for (short i = 0; i < calcs.SubPoints.Length; i++) calcs.OverallPoints += calcs.SubPoints[i]; return calcs; }
public void StateSpaceGeneratorFuryTest1(Character c, Stats s, CombatFactors cf, Skills.WhiteAttacks wa, CalculationOptionsDPSWarr co, BossOptions bo, bool showOutput) { FuryGenerator gen = new FuryGenerator(c, s, cf, wa, co, bo); #if !SILVERLIGHT System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); #endif List <State <Skills.Ability> > stateSpace = gen.GenerateStateSpace(); #if !SILVERLIGHT sw.Stop(); Console.WriteLine("GenStateSpace: " + sw.ElapsedTicks); #endif if (showOutput) { try { int numIterations = 0; gen.HSPerc = 1; double oldDPS = 0; while (numIterations < 2) { double averageDamage = 0; double rageNeededNoHS = 0f; #if !SILVERLIGHT sw = System.Diagnostics.Stopwatch.StartNew(); #endif MarkovProcess <Skills.Ability> mp2 = new MarkovProcess <Rawr.DPSWarr.Skills.Ability>(stateSpace); #if !SILVERLIGHT sw.Stop(); Console.WriteLine("MarkovProcess._ctor: " + sw.ElapsedTicks); #endif foreach (KeyValuePair <Skills.Ability, double> kvp in mp2.AbilityWeight) { #if RAWR3 || SILVERLIGHT rageNeededNoHS += kvp.Key.RageCost * (kvp.Value * bo.BerserkTimer / mp2.AverageTransitionDuration); #else rageNeededNoHS += kvp.Key.RageCost * (kvp.Value * co.Duration / mp2.AverageTransitionDuration); #endif averageDamage += kvp.Key.DamageOnUse * kvp.Value; } double hsdps = gen.Rot.GetWrapper <Skills.HeroicStrike>().ability.DamageOnUse / wa.MhEffectiveSpeed * gen.HSPerc; double mhdps = wa.MhDamageOnUse / wa.MhEffectiveSpeed * (1 - gen.HSPerc); double ohdps = gen.Rot.WhiteAtks.OhDPS; double dps = averageDamage / mp2.AverageTransitionDuration; dps += hsdps + mhdps + ohdps; System.Console.WriteLine(String.Format("DPS: {0} || HSPerc: {1}", dps, gen.HSPerc)); double rageNeeded = rageNeededNoHS; Skills.HeroicStrike HS = gen.Rot.GetWrapper <Skills.HeroicStrike>().ability as Skills.HeroicStrike; #if RAWR3 || SILVERLIGHT rageNeeded += HS.FullRageCost * (bo.BerserkTimer / wa.MhEffectiveSpeed * gen.HSPerc); double rageGenerated = wa.MHSwingRage * (bo.BerserkTimer / wa.MhEffectiveSpeed) + wa.OHSwingRage * (bo.BerserkTimer / wa.OhEffectiveSpeed); #else rageNeeded += HS.FullRageCost * (co.Duration / wa.MhEffectiveSpeed * gen.HSPerc); double rageGenerated = wa.MHSwingRage * (co.Duration / wa.MhEffectiveSpeed) + wa.OHSwingRage * (co.Duration / wa.OhEffectiveSpeed); #endif double HsRage = rageNeeded - rageNeededNoHS; double hsRageNeeded = rageGenerated - rageNeededNoHS; gen.HSPerc = Math.Min((hsRageNeeded / HS.FullRageCost) / #if RAWR3 || SILVERLIGHT (bo.BerserkTimer / wa.MhEffectiveSpeed), 1); // Needed HS Activates / White activates #else (co.Duration / wa.MhEffectiveSpeed), 1); // Needed HS Activates / White activates #endif oldDPS = dps; numIterations++; } /*MarkovProcess<Skills.Ability> mp = new MarkovProcess<Skills.Ability>(stateSpace); * * double averageDamage2 = 0.0; * foreach (KeyValuePair<Skills.Ability, double> kvp in mp.AbilityWeight) * { * if (showOutput) System.Console.WriteLine("{0} - {1}", kvp.Key.Name, kvp.Key.DamageOnUse * kvp.Value / mp.AverageTransitionDuration); * averageDamage2 += kvp.Key.DamageOnUse * kvp.Value; * } * double hsdps2 = gen.Rot.GetWrapper<Skills.HeroicStrike>().ability.DamageOnUse / wa.MhEffectiveSpeed * gen.HSPerc; * double mhdps2 = wa.MhDamageOnUse / wa.MhEffectiveSpeed * (1 - gen.HSPerc); * double ohdps2 = gen.Rot.WhiteAtks.OhDPS; * if (showOutput) * { * System.Console.WriteLine("HS - {0}", hsdps2); * System.Console.WriteLine("MH - {0}", mhdps2); * System.Console.WriteLine("OH - {0}", ohdps2); * } * double dps2 = averageDamage2 / mp.AverageTransitionDuration; * dps2 += hsdps2 + mhdps2 + ohdps2;*/ } catch (Exception ex) { new ErrorBox("Error in creating Arms Markov Calculations", ex.Message, "StateSpaceGeneratorArmsTest1()", "StateSpace Count: " + stateSpace.Count.ToString(), ex.StackTrace); } } }
internal CharacterCalculationsBase GetCharacterCalculations(Character character) { CharacterCalculationsRestoSham calcs = new CharacterCalculationsRestoSham() { BasicStats = _TotalStats.Clone(), BurstSequence = _CalculationOptions.BurstStyle, SustainedSequence = _CalculationOptions.SustStyle, MailSpecialization = (GetArmorSpecializationStatus(character) ? 0.05f : 0f) }; float healingCriticalScale = 1.5f * (1 + _TotalStats.BonusCritHealMultiplier); float dmgCriticalScale = 2f * (1 + _TotalStats.BonusCritDamageMultiplier); float hasteScale = 1f / (1f + _TotalStats.SpellHaste); calcs.SustainedHPS = 0f; calcs.BurstHPS = 0f; foreach (HealingSpell spell in _AvailableSpells.OfType <HealingSpell>()) { spell.EffectModifier *= (1 + _TotalStats.BonusHealingDoneMultiplier); spell.CriticalScale = healingCriticalScale; spell.HasteScale = hasteScale; spell.Latency = _Latency; spell.GcdLatency = _GcdLatency; spell.SpellPower = _TotalStats.SpellPower; spell.CritRate = _TotalStats.SpellCrit; spell.Calculate(); calcs.SustainedHPS += spell.EPS; if (spell is EarthShield) { calcs.ESHPS = spell.EPS; } } foreach (LightningBolt spell in _AvailableSpells.OfType <LightningBolt>()) { spell.EffectModifier *= (1 + _TotalStats.BonusDamageMultiplier); spell.CriticalScale = dmgCriticalScale; spell.HasteScale = hasteScale; spell.Latency = _Latency; spell.GcdLatency = _GcdLatency; spell.SpellPower = _TotalStats.SpellPower; spell.CritRate = _TotalStats.SpellCrit; spell.Calculate(); calcs.LBRestore = spell.ManaBack - spell.ManaCost; calcs.LBCast = spell.CastTime; } float mp5 = _TotalStats.Mp5 + (_TotalStats.ManaRestoreFromMaxManaPerSecond * _TotalStats.Mana); if (_PerformSequencing) { { StateMachine.StateGenerator gen = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Burst, _TotalStats.Mana, mp5); List <State <Spell> > stateSpace = gen.GenerateStateSpace(); MarkovProcess <Spell> mp = new MarkovProcess <Spell>(stateSpace); _BurstSpellSequence = new Dictionary <Spell, double>(mp.AbilityWeight); _BurstSequenceDuration = mp.AverageTransitionDuration; } { StateMachine.StateGenerator gen = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Sustained, _TotalStats.Mana, mp5); List <State <Spell> > stateSpace = gen.GenerateStateSpace(); MarkovProcess <Spell> mp = new MarkovProcess <Spell>(stateSpace); _SustSpellSequence = new Dictionary <Spell, double>(mp.AbilityWeight); _SustSequenceDuration = mp.AverageTransitionDuration; } if (_PerformSequencing) { _SequencedStats = _TotalStats.Clone(); } } if (_BurstSpellSequence != null) { double avgHealing = 0d; string seq = ""; string seqShort = ""; foreach (var item in _BurstSpellSequence) { if (item.Key is HealingSpell) { if (seq.Length > 0) { seqShort += ","; seq += ", "; } seqShort += item.Key.SpellAbrv; seq += item.Key.SpellName; avgHealing += item.Key.Effect * item.Value; if (item.Key is Hot) { avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value; } } } double hps = avgHealing / _BurstSequenceDuration; calcs.BurstHPS = (float)hps; calcs.BurstSequence = seq; calcs.BurstSequenceShort = seqShort; } if (_SustSpellSequence != null) { double avgHealing = 0d; string seq = ""; string seqShort = ""; foreach (var item in _SustSpellSequence) { if (item.Key is HealingSpell) { if (seq.Length > 0) { seqShort += ","; seq += ", "; } seqShort += item.Key.SpellAbrv; seq += item.Key.SpellName; avgHealing += item.Key.Effect * item.Value; if (item.Key is Hot) { avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value; } } } double hps = avgHealing / _SustSequenceDuration; calcs.SustainedHPS = (float)hps; calcs.SustainedSequence = seq; calcs.SustainedSequenceShort = seqShort; } if (calcs.BurstHPS < 0f) { calcs.BurstHPS = 0f; } if (calcs.SustainedHPS < 0f) { calcs.SustainedHPS = 0f; } if (calcs.Survival < 0f) { calcs.Survival = 0f; } calcs.Survival = (calcs.BasicStats.Health + calcs.BasicStats.Hp5) * (_CalculationOptions.SurvivalPerc * .01f); // Set the sub categories calcs.SubPoints[0] = calcs.BurstHPS; calcs.SubPoints[1] = calcs.SustainedHPS; calcs.SubPoints[2] = calcs.Survival; // Sum up calcs.OverallPoints = 0f; for (short i = 0; i < calcs.SubPoints.Length; i++) { calcs.OverallPoints += calcs.SubPoints[i]; } return(calcs); }
public void MarkovProcessTest1() { //S0: //A => S0 0.5 // => S1 0.5 //S1: //B => S0 1 Ability A = new Ability() { Damage = 100, Duration = 2 }; Ability B = new Ability() { Damage = 200, Duration = 1 }; State <Ability> S0 = new State <Ability>() { Name = "S0" }; State <Ability> S1 = new State <Ability>() { Name = "S1" }; S0.Transitions = new List <StateTransition <Ability> >() { new StateTransition <Ability>() { Ability = A, TargetState = S0, TransitionDuration = A.Duration, TransitionProbability = 0.5 }, new StateTransition <Ability>() { Ability = A, TargetState = S1, TransitionDuration = A.Duration, TransitionProbability = 0.5 }, }; S1.Transitions = new List <StateTransition <Ability> >() { new StateTransition <Ability>() { Ability = B, TargetState = S0, TransitionDuration = B.Duration, TransitionProbability = 1.0 }, }; List <State <Ability> > stateSpace = new List <State <Ability> >() { S0, S1 }; MarkovProcess <Ability> mp = new MarkovProcess <Ability>(stateSpace); Assert.AreEqual(mp.StateWeight[0], 2.0 / 3.0, 0.000000000001, "S0"); Assert.AreEqual(mp.StateWeight[1], 1.0 / 3.0, 0.000000000001, "S1"); Assert.AreEqual(mp.AverageTransitionDuration, 5.0 / 3.0, 0.000000000001, "time"); double averageDamage = 0.0; foreach (KeyValuePair <Ability, double> kvp in mp.AbilityWeight) { averageDamage += kvp.Key.Damage * kvp.Value; } Assert.AreEqual(averageDamage, 100.0 * 4.0 / 3.0, 0.000000000001, "damage"); Assert.AreEqual(averageDamage / mp.AverageTransitionDuration, 80.0, 0.000000000001, "dps"); double[] stateLengths = mp.GetAverageTimeToEnd(st => (st.Name == "S1")); Assert.AreEqual(stateLengths[0], 4.0, "time to end"); }
public void MarkovProcessTest1() { //S0: //A => S0 0.5 // => S1 0.5 //S1: //B => S0 1 Ability A = new Ability() { Damage = 100, Duration = 2 }; Ability B = new Ability() { Damage = 200, Duration = 1 }; State<Ability> S0 = new State<Ability>() { Name = "S0" }; State<Ability> S1 = new State<Ability>() { Name = "S1" }; S0.Transitions = new List<StateTransition<Ability>>() { new StateTransition<Ability>() { Ability = A, TargetState = S0, TransitionDuration = A.Duration, TransitionProbability = 0.5 }, new StateTransition<Ability>() { Ability = A, TargetState = S1, TransitionDuration = A.Duration, TransitionProbability = 0.5 }, }; S1.Transitions = new List<StateTransition<Ability>>() { new StateTransition<Ability>() { Ability = B, TargetState = S0, TransitionDuration = B.Duration, TransitionProbability = 1.0 }, }; List<State<Ability>> stateSpace = new List<State<Ability>>() { S0, S1 }; MarkovProcess<Ability> mp = new MarkovProcess<Ability>(stateSpace); Assert.AreEqual(mp.StateWeight[0], 2.0 / 3.0, 0.000000000001, "S0"); Assert.AreEqual(mp.StateWeight[1], 1.0 / 3.0, 0.000000000001, "S1"); Assert.AreEqual(mp.AverageTransitionDuration, 5.0 / 3.0, 0.000000000001, "time"); double averageDamage = 0.0; foreach (KeyValuePair<Ability, double> kvp in mp.AbilityWeight) { averageDamage += kvp.Key.Damage * kvp.Value; } Assert.AreEqual(averageDamage, 100.0 * 4.0 / 3.0, 0.000000000001, "damage"); Assert.AreEqual(averageDamage / mp.AverageTransitionDuration, 80.0, 0.000000000001, "dps"); double[] stateLengths = mp.GetAverageTimeToEnd(st => (st.Name == "S1")); Assert.AreEqual(stateLengths[0], 4.0, "time to end"); }
public void MarkovProcessTest3() { //S0: //AB-ABar1 => S0 0.8 * 0.8 // => S1 1 - 0.8 * 0.8 //S1: //MBAM-ABar => S0 0.8 // => S1 0.2 Ability AB = new Ability(); Ability ABar1 = new Ability(); Ability MBAM = new Ability(); Ability ABar = new Ability(); Ability ABABar1 = new AbilitySequence(AB, ABar1); Ability MBAMABar = new AbilitySequence(MBAM, ABar); State<Ability> S0 = new State<Ability>() { Name = "S0" }; State<Ability> S1 = new State<Ability>() { Name = "S1" }; S0.Transitions = new List<StateTransition<Ability>>() { new StateTransition<Ability>() { Ability = ABABar1, TargetState = S0, TransitionDuration = ABABar1.Duration, TransitionProbability = 0.8 * 0.8 }, new StateTransition<Ability>() { Ability = ABABar1, TargetState = S1, TransitionDuration = ABABar1.Duration, TransitionProbability = 1.0 - 0.8 * 0.8 }, }; S1.Transitions = new List<StateTransition<Ability>>() { new StateTransition<Ability>() { Ability = MBAMABar, TargetState = S0, TransitionDuration = MBAMABar.Duration, TransitionProbability = 0.8 }, new StateTransition<Ability>() { Ability = MBAMABar, TargetState = S1, TransitionDuration = MBAMABar.Duration, TransitionProbability = 0.2 }, }; List<State<Ability>> stateSpace = new List<State<Ability>>() { S0, S1 }; MarkovProcess<Ability> mp = new MarkovProcess<Ability>(stateSpace); Assert.AreEqual(mp.StateWeight[0], 0.69, 0.01, "S0"); Assert.AreEqual(mp.StateWeight[1], 0.31, 0.01, "S1"); }
public void MarkovProcessTest2() { //S0: //A => S0 0.5 //AB => S0 0.5 Ability A = new Ability() { Damage = 100, Duration = 2 }; Ability B = new Ability() { Damage = 200, Duration = 1 }; Ability AB = new AbilitySequence(A, B); State<Ability> S0 = new State<Ability>() { Name = "S0" }; S0.Transitions = new List<StateTransition<Ability>>() { new StateTransition<Ability>() { Ability = A, TargetState = S0, TransitionDuration = A.Duration, TransitionProbability = 0.5 }, new StateTransition<Ability>() { Ability = AB, TargetState = S0, TransitionDuration = AB.Duration, TransitionProbability = 0.5 }, }; List<State<Ability>> stateSpace = new List<State<Ability>>() { S0 }; MarkovProcess<Ability> mp = new MarkovProcess<Ability>(stateSpace); Assert.AreEqual(mp.StateWeight[0], 1.0, 0.000000000001, "S0"); Assert.AreEqual(mp.AverageTransitionDuration, 2.5, 0.000000000001, "time"); double averageDamage = 0.0; foreach (KeyValuePair<Ability, double> kvp in mp.AbilityWeight) { averageDamage += kvp.Key.Damage * kvp.Value; } Assert.AreEqual(averageDamage, 200.0, "damage"); Assert.AreEqual(averageDamage / mp.AverageTransitionDuration, 80.0, 0.000000000001, "dps"); }