Beispiel #1
0
    public void Compare_ValueAgainstNull_equalValueAtEnd_True()
    {
        string test_string = "test";
        DuplicateKeyComparer <string> dkc_int = new DuplicateKeyComparer <string>(true);

        Assert.Greater(dkc_int.Compare(test_string, null), 0);
    }
Beispiel #2
0
    public void Compare_NullAgainstValue_equalValueAtEnd_True()
    {
        string test_string = "test";
        DuplicateKeyComparer <string> dkc_int = new DuplicateKeyComparer <string>(true);

        Assert.Throws(typeof(NullReferenceException), () => dkc_int.Compare(null, test_string));
    }
    public void Compare_NullAgainstValue_equalValueAtEnd_True()
    {
        string test_string = "test";
        DuplicateKeyComparer <string> dkc_int = new DuplicateKeyComparer <string>(true);

        dkc_int.Compare(null, test_string);
    }
Beispiel #4
0
        /// <summary>
        /// Evaluates the given Ability being used by the provided CombatEntity against all of the
        /// Formations currently in the battle.
        /// <para>Returns the best target location and target Formation altered by the AiRandomnessFactor
        /// of this Ai's Formation.</para>
        /// </summary>
        /// <param name="activeEntity">The CombatEntity who's ability is being evaluated.</param>
        /// <param name="ability">The Ability being evaluated.</param>
        /// <returns></returns>
        private AbilityEvaluation EvaluateAbility(CombatEntity activeEntity, Ability ability)
        {
            var comparer    = new DuplicateKeyComparer();
            var evaluations = new SortedList <int, AbilityEvaluation>(comparer);

            foreach (var enemy in _myEnemies)
            {
                var evaluation = EvaluateFormation(activeEntity, ability, enemy, true);
                if (evaluation == null)
                {
                    continue;
                }

                evaluations.Add(evaluation.TotalValue, new AbilityEvaluation
                {
                    Ability             = ability,
                    FormationEvaluation = evaluation,
                    TargetFormation     = enemy
                });
            }

            foreach (var ally in _myAllies)
            {
                var evaluation = EvaluateFormation(activeEntity, ability, ally, false);
                if (evaluation == null)
                {
                    continue;
                }

                evaluations.Add(evaluation.TotalValue, new AbilityEvaluation
                {
                    Ability             = ability,
                    FormationEvaluation = evaluation,
                    TargetFormation     = ally
                });
            }

            if (evaluations.Count == 0)
            {
                return(null);
            }

            // If no ai randomness, choose highest value FormationEvaluation
            if (_myFormation.AiRandomness <= 0)
            {
                return(evaluations.Last().Value);
            }
            // Randomly choose from the highest value FormationEvaluation if any ai randomness
            else
            {
                var highestValues = evaluations.TakeLast(_myFormation.AiRandomness + 1)
                                    .Select(kvp => kvp.Value);

                var random = _rand.Next(highestValues.Count());

                return(highestValues.ElementAt(random));
            }
        }
Beispiel #5
0
    public void Compare_AgainstSelf_equalValueAtEnd_True()
    {
        // test on int
        int test_int = 1;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>(true);

        Assert.Less(dkc_int.Compare(test_int, test_int), 0);
    }
Beispiel #6
0
    public void Compare_AgainstSelf_equalValueAtEnd_False()
    {
        // test on int
        int test_int = 1;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>(false);

        Assert.Greater(dkc_int.Compare(test_int, test_int), 0);
    }
Beispiel #7
0
    public void Compare_AgainstSelf()
    {
        // test on int
        int test_int = 1;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>();

        Assert.Greater(dkc_int.Compare(test_int, test_int), 0);
    }
Beispiel #8
0
    public void Compare_AgainstCopy_equalValueAtEnd_True()
    {
        // test on int
        int test_int_a = 1;
        int test_int_b = test_int_a;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>(true);

        Assert.Less(dkc_int.Compare(test_int_a, test_int_b), 0);
    }
Beispiel #9
0
    public void Compare_AgainstCopy_equalValueAtEnd_False()
    {
        // test on int
        int test_int_a = 1;
        int test_int_b = test_int_a;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>(false);

        Assert.Greater(dkc_int.Compare(test_int_a, test_int_b), 0);
    }
Beispiel #10
0
    public void Compare_AgainstCopy()
    {
        // test on int
        int test_int_a = 1;
        int test_int_b = test_int_a;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>();

        Assert.Greater(dkc_int.Compare(test_int_a, test_int_b), 0);
    }
Beispiel #11
0
    public void Compare_AgainstSmallerValue_equalValueAtEnd_True()
    {
        // test on two int's with a < b
        int test_int_a = 2;
        int test_int_b = 1;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>(true);

        Assert.Greater(dkc_int.Compare(test_int_a, test_int_b), 0);
    }
Beispiel #12
0
    public void Compare_AgainstLargerValue_equalValueAtEnd_Flase()
    {
        // test on two int's with a < b
        int test_int_a = 1;
        int test_int_b = 2;

        DuplicateKeyComparer <int> dkc_int = new DuplicateKeyComparer <int>(false);

        Assert.Less(dkc_int.Compare(test_int_a, test_int_b), 0);
    }
Beispiel #13
0
    public void Compare_NullAgainstNull()
    {
        DuplicateKeyComparer <string> dkc_int = new DuplicateKeyComparer <string>();

        Assert.Throws(typeof(NullReferenceException), () => dkc_int.Compare(null, null));
    }
    public void Compare_NullAgainstNull()
    {
        DuplicateKeyComparer <string> dkc_int = new DuplicateKeyComparer <string>();

        dkc_int.Compare(null, null);
    }
Beispiel #15
0
        /// <summary>
        /// Returns a FormationEvaluation for the given CombatEntity which will use the given Ability on
        /// the provided Formation.
        /// <para>The FormationEvaluation will contain the best target location for the given Ability depending
        /// on the AiRandomnesFactor for the ai Formation.</para>
        /// </summary>
        /// <param name="activeEntity">The CombatEntity that will be acting.</param>
        /// <param name="ability">The Ability being evaluated.</param>
        /// <param name="formation">The Formation being targeted.</param>
        /// <param name="isEnemyFormation">True if the provided Formation is an enemy Formation. False if allied.</param>
        /// <returns></returns>
        private FormationEvaluation EvaluateFormation(CombatEntity activeEntity,
                                                      Ability ability,
                                                      Formation formation,
                                                      bool isEnemyFormation)
        {
            bool isOffensive = ability.IsOffensive.GetValueOrDefault();

            // Only allows offensive abilities against enemy formations and defensive abilities on allied formations
            if ((!isOffensive && isEnemyFormation) || (isOffensive && !isEnemyFormation))
            {
                return(null);
            }

            var comparer    = new DuplicateKeyComparer();
            var evaluations = new SortedList <int, FormationEvaluation>(comparer);

            // Calculate total ai weight modifier for this ability
            int aiWeightModifier = ability.SelfAppliedStatusEffects.Concat(ability.AppliedStatusEffects)
                                   .Select(status => status.AiWeightModifier)
                                   .Sum();

            aiWeightModifier += ability.AiWeightModifier;

            // Evaluate every target in the formation and record the evaluations in the SortedList
            for (int i = 0; i < formation.Positions.Length; i++)
            {
                for (int j = 0; j < formation.Positions[i].Length; j++)
                {
                    int newCenter = i * GameplayConstants.MaxFormationRows + j + 1;
                    var targets   = FormationTargeter.GetTargets(ability, newCenter, formation);

                    // No valid targets, skip this position
                    if (targets == null || targets.Count() <= 0)
                    {
                        continue;
                    }

                    int totalThreat = targets.Select(entity => entity.Threat)
                                      .Sum();

                    // Calculate total value using damage if using the ability offensively
                    if (isEnemyFormation && isOffensive)
                    {
                        // Ignore dead entities
                        targets = targets.Where(entity => entity.Resources.CurrentHealth > 0).ToList();
                        if (targets.Count() == 0)
                        {
                            continue;
                        }

                        // Gets total potential damage dealt to each target as a percentage
                        int damagePercentage = targets.Select(entity =>
                        {
                            int damage          = DamageCalculator.GetTotalDamageAsInt(activeEntity, entity, ability);
                            int damageAsPercent = damage * 100 / entity.Resources.MaxHealth;

                            return(damageAsPercent + DamageCalculator.GetPercentageDamageAsInt(entity, ability));
                        }).Sum();

                        int totalValue = totalThreat + damagePercentage + aiWeightModifier;

                        evaluations.Add(totalValue, new FormationEvaluation
                        {
                            TargetLocation = newCenter,
                            TotalValue     = totalValue
                        });
                    }

                    // Calculate total value using healing if using the ability defensively
                    else if (!isEnemyFormation && !isOffensive)
                    {
                        // Ignore dead entities, update later when adding resurrection spells
                        targets = targets.Where(entity => entity.Resources.CurrentHealth > 0).ToList();
                        if (targets.Count() == 0)
                        {
                            continue;
                        }

                        int healPercentage = targets.Select(entity =>
                        {
                            // Value cannot exceed max heal amount, prevents ai from wanting to overheal
                            int maxHealPercent = 100 - (entity.Resources.CurrentHealth * 100 / entity.Resources.MaxHealth);
                            int healPercent    = DamageCalculator.GetHeal(activeEntity, ability) * 100 / entity.Resources.MaxHealth;
                            healPercent       += ability.PercentHeal;

                            return((healPercent > maxHealPercent) ? maxHealPercent : healPercent);
                        }).Sum();

                        int totalValue = totalThreat + healPercentage + aiWeightModifier;

                        evaluations.Add(totalValue, new FormationEvaluation
                        {
                            TargetLocation = newCenter,
                            TotalValue     = totalValue
                        });
                    }
                }
            }

            if (evaluations.Count == 0)
            {
                return(null);
            }

            // Returns best target evaluation if no randomness
            if (_myFormation.AiRandomness <= 0)
            {
                return(evaluations.Last().Value);
            }

            // If any ai randomness, choose randomly between the best targets
            else
            {
                var highestValues = evaluations.TakeLast(_myFormation.AiRandomness + 1)
                                    .Select(kvp => kvp.Value);

                var random = _rand.Next(highestValues.Count());

                return(highestValues.ElementAt(random));
            }
        }
Beispiel #16
0
        /// <summary>
        /// Makes a CombatAiDecision for the provided CombatEntity.
        /// <para>Will choose the best Ability, target Formation, and target Coordinate unless the AiRandomnessFactor
        /// for the provided CombatEntity's Formation is not 0.</para>
        /// </summary>
        /// <param name="activeEntity">The CombatEntity to make a decision for.</param>
        /// <returns>A decision on what Ability to use and where in combat.</returns>
        private CombatAiDecision EvaluateEntity(CombatEntity activeEntity)
        {
            var comparer    = new DuplicateKeyComparer();
            var evaluations = new SortedList <int, AbilityEvaluation>(comparer);

            // Get any abilities not in the CombatEntity's cooldowns list
            var useableAbilities = activeEntity.Abilities.Where(ability =>
            {
                return(!activeEntity.AbilitiesOnCooldown.Any(kvp => kvp.Key.Id == ability.Id));
            });

            foreach (var ability in useableAbilities)
            {
                var abilityEvaluation = EvaluateAbility(activeEntity, ability);
                if (abilityEvaluation == null)
                {
                    continue;
                }

                evaluations.Add(abilityEvaluation.FormationEvaluation.TotalValue, abilityEvaluation);
            }

            // Checks if any abilities are under the desired value
            bool areAbilitiesUnderPar = evaluations.Keys.Any(value => value <= UnderParThreshold);

            // If there are no valid abilities or all abilities are under par, perform a defend action instead
            if (evaluations.Count() == 0 || areAbilitiesUnderPar)
            {
                return(new CombatAiDecision
                {
                    IsDefending = true
                });
            }

            // If no ai randomness, choose highest value AbilityEvaluation
            if (_myFormation.AiRandomness <= 0)
            {
                var evaluation = evaluations.Last().Value;
                var coordinate = new Coordinate
                {
                    PositionX = evaluation.FormationEvaluation.TargetLocation % GameplayConstants.MaxFormationColumns,
                    PositionY = evaluation.FormationEvaluation.TargetLocation / GameplayConstants.MaxFormationRows
                };

                return(new CombatAiDecision
                {
                    Ability = evaluation.Ability,
                    Actor = activeEntity,
                    TargetCoordinate = coordinate,
                    TargetFormation = evaluation.TargetFormation
                });
            }
            // Randomly choose from the highest value AbilityEvaluation if any ai randomness
            else
            {
                var highestValues = evaluations.TakeLast(_myFormation.AiRandomness + 1)
                                    .Select(kvp => kvp.Value);

                var random = _rand.Next(highestValues.Count());

                var chosenEvaluation = highestValues.ElementAt(random);
                var coordinate       = new Coordinate
                {
                    PositionX = chosenEvaluation.FormationEvaluation.TargetLocation % GameplayConstants.MaxFormationColumns,
                    PositionY = chosenEvaluation.FormationEvaluation.TargetLocation / GameplayConstants.MaxFormationRows
                };

                return(new CombatAiDecision
                {
                    Ability = chosenEvaluation.Ability,
                    Actor = activeEntity,
                    TargetCoordinate = coordinate,
                    TargetFormation = chosenEvaluation.TargetFormation
                });
            }
        }