Esempio n. 1
0
        public static bool ShouldAttack(this Elf e, GameObject target)
        {
            var possibleAttackers = LocationFinder.GetPossibleAttackers(e);

            // the damage to the target is the damage by the elf and the suffocation damage
            int damageToTarget    = e.AttackMultiplier + target.GetSuffocationPerTurn();
            int turnsToKillTarget = (int)System.Math.Ceiling(1.0 * target.CurrentHealth / damageToTarget);

            // the damage done to the elf can be different every turn
            int health = e.CurrentHealth;

            for (int i = 0; i < turnsToKillTarget; i++)
            {
                foreach (var attacker in possibleAttackers)
                {
                    if (attacker.CurrentHealth <= attacker.GetSuffocationPerTurn() * i)
                    {
                        continue;
                    }
                    health -= attacker.GetAttackMultiplier();
                }
            }

            System.Console.WriteLine($"{health}:{turnsToKillTarget}:{target.Type}:{possibleAttackers.Count}");

            // if the number of turns to kill the target are smaller then the number of turns to kill the elf
            // then elf will win the fight
            return(health == e.CurrentHealth || health >= GameState.Game.ElfMaxHealth / 2 || (target is Elf && health >= 0));
        }
Esempio n. 2
0
        /// <summary>
        ///     returns the target the elf should go and attack. exceptions are ignored
        /// </summary>
        /// <param name="e"> elf object </param>
        /// <param name="exceptions"></param>
        /// <returns></returns>
        public static GameObject GetMoveTarget(this Elf e, params GameObject[] exceptions)
        {
            IEnumerable <GameObject> allTargets = ((GameObject[])GameState.Game.GetEnemyPortals())
                                                  .Concat(GameState.Game.GetEnemyManaFountains())
                                                  .Concat(GameState.EnemyLivingElves);

            return((from target in allTargets
                    let attackLocation = e.GetAttackLocation(target)
                                         where !exceptions.Contains(target) &&
                                         (!(target is Elf) || target.CurrentHealth <= e.CurrentHealth)
                                         orderby LocationFinder.GetPossibleAttackers(e, attackLocation, exceptions: target).Count,
                    e.Distance(attackLocation),
                    target is Portal ? target.Distance(GameState.MyCastle) : int.MaxValue,
                    target is ManaFountain ? 0 : 1,
                    target.CurrentHealth
                    select target).FirstOrDefault());
        }
Esempio n. 3
0
        /// <summary>
        ///     Returns true if it is safe to stay at the current location.
        ///     Exceptions are ignored
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="turns"></param>
        /// <param name="exceptions"></param>
        /// <returns></returns>
        public static bool SafeNotToMove(this GameObject obj, int turns = 1, params GameObject[] exceptions)
        {
            if (turns == 1)
            {
                return(LocationFinder.GetPossibleAttackers(obj, exceptions: exceptions).Count == 0);
            }

            int health = obj.CurrentHealth;
            int size   = 0;

            if (obj is Building b)
            {
                size = b.Size;
            }
            var enemies = GameState.EnemyLivingElves.Cast <GameObject>()
                          .Concat(GameState.EnemyLivingIceTrolls.Where(troll => troll.GetTarget().Equals(obj))).ToList();
            var locations = GameState.EnemyLivingElves.Cast <GameObject>()
                            .Concat(GameState.EnemyLivingIceTrolls)
                            .ToDictionary(g => g, g => g.Location);

            // we simulate the turns
            for (int turn = 1; turn <= turns; turn++)
            {
                var enemiesToRemove = new List <GameObject>();
                foreach (var enemy in enemies)
                {
                    if (locations[enemy].InRange(obj, enemy.GetAttackRange() + size))
                    {
                        health -= enemy.GetAttackMultiplier();
                    }
                    else
                    {
                        locations[enemy] = locations[enemy].Towards(obj, enemy.GetMaxSpeed());
                    }

                    if (enemy.CurrentHealth - enemy.GetSuffocationPerTurn() * turn <= 0)
                    {
                        enemiesToRemove.Add(enemy);
                    }
                }
                enemies.RemoveAll(enemiesToRemove.Contains);
            }

            return(health > 0 && obj.CurrentHealth - health <= obj.MaxHealth / 2);
        }
Esempio n. 4
0
        public static void MoveToCastle(Elf e)
        {
            Location attackLocation =
                GameState.EnemyCastle.Location.Towards(e, e.AttackRange + GameState.EnemyCastle.Size);

            if (e.Location.Equals(attackLocation))
            {
                if (e.ShouldAttack(GameState.EnemyCastle))
                {
                    e.Attack(GameState.EnemyCastle);
                    return;
                }

                var target = e.GetAttackTarget();
                if (target is Elf && LocationFinder.GetPossibleAttackers(e, exceptions: target).Count == 0)
                {
                    e.Attack(target);
                    return;
                }
            }
            e.MoveSafely(attackLocation);
        }