コード例 #1
0
        private static bool ResolveMultiShot(List <AttackTarget> results, List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets)
        {
            List <DamageMap> damageMap = BuildDamageMap(units, unitTargets);

            foreach (DamageMap map in damageMap)
            {
                Entity enemy       = map.Enemy;
                int    enemyHealth = enemy.Health;
                if (enemy.CanAttack && enemyHealth < map.Damage)
                {
                    int damage = 0;
                    foreach (Entity unit in map.Units)
                    {
                        results.Add(new AttackTarget(unit, enemy));
                        damage += unit.AttackDamage;

                        if (damage >= enemyHealth)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
コード例 #2
0
        private static bool ResolveSimple(List <AttackTarget> results, List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets)
        {
            foreach (Entity unit in units)
            {
                EntityTarget        bestTarget = null;
                List <EntityTarget> targets    = unitTargets[unit.Id];

                foreach (EntityTarget target in targets)
                {
                    Entity enemy = target.Entity;
                    if (bestTarget == null || (enemy.CanAttack && enemy.Health < bestTarget.Entity.Health))
                    {
                        bestTarget = target;
                    }
                }

                if (bestTarget != null)
                {
                    results.Add(new AttackTarget(unit, bestTarget.Entity));
                    return(true);
                }
            }

            return(false);
        }
コード例 #3
0
        private static bool TryGetClosestFacility(Entity builder, out Entity facility)
        {
            Point position = builder.Position;

            if (position.X > 0 && TryGetClosestFacility(position.Left, out facility) ||
                position.Y > 0 && TryGetClosestFacility(position.Down, out facility) ||
                position.X + 1 < World.Size && TryGetClosestFacility(position.Right, out facility) ||
                position.Y + 1 < World.Size && TryGetClosestFacility(position.Up, out facility))
            {
                return(true);
            }

            facility = null;
            return(false);
        }
コード例 #4
0
        private static bool TryGetClosestFacility(Point position, out Entity facility)
        {
            Entity entity = World.Get(position).Entity;

            if (entity == null)
            {
                facility = default;
                return(false);
            }

            if (entity.My && entity.Facility && entity.Health < entity.MaxHealth)
            {
                facility = entity;
                return(true);
            }

            facility = default;
            return(false);
        }
コード例 #5
0
        private static bool ResolveOneShot(List <AttackTarget> results, List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets)
        {
            List <DamageMap> damageMap = BuildDamageMap(units, unitTargets);

            foreach (DamageMap map in damageMap)
            {
                Entity enemy = map.Enemy;
                if (enemy.CanAttack && map.Units.Count == 1) // attacked only single unit
                {
                    Entity unit = map.Units[0];
                    if (enemy.Health <= unit.AttackDamage)
                    {
                        results.Add(new AttackTarget(unit, enemy));
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #6
0
        private static void MineClosestMineral(List <Entity> builders)
        {
            foreach (Entity builder in builders.Clone())
            {
                Point         position  = builder.Position;
                List <Entity> resources = Helper
                                          .GetNeighbors(position)
                                          .AsEntities()
                                          .Where(e => e.Mineral)
                                          .ToList();

                if (resources.Count == 0)
                {
                    continue;
                }

                Entity mineral = Dice.Roll(resources);
                builder.Action = Actions.Attack(mineral);
                builders.Remove(builder);
            }
        }
コード例 #7
0
        private static List <DamageMap> BuildDamageMap(List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets)
        {
            Dictionary <int, DamageMap> damages = new Dictionary <int, DamageMap>();

            foreach (Entity unit in units)
            {
                List <EntityTarget> targets = unitTargets[unit.Id];

                foreach (EntityTarget target in targets)
                {
                    Entity enemy = target.Entity;
                    if (!damages.TryGetValue(enemy.Id, out var damage))
                    {
                        damage = new DamageMap(enemy);
                        damages.Add(enemy.Id, damage);
                    }

                    damage.Add(unit);
                }
            }

            return(damages.Values.ToList());
        }
コード例 #8
0
        private static void ProduceUnit(Entity factory)
        {
            if (!factory.Active)
            {
                return; // not ready
            }

            EntityType unitType = GetProduceEntityType(factory.Type);
            EntityInfo info     = World.Info[unitType];

            if (World.Money < info.Cost)
            {
                return; // no money
            }

            if (World.Population + World.PopulationUse == World.MaxPopulation)
            {
                return; // no living space
            }

            List <Point> spawns = Helper.GetFacilityTerritory(factory, IsFree);

            if (spawns.Count == 0)
            {
                return;
            }

            Point spawn = Dice.Roll(spawns);

            factory.Action = Actions.Build(unitType, spawn);
            World.Get(spawn).ReservedForEntity = factory;

            World.Money             -= info.Cost;
            World.PopulationUse     += info.PopulationUse;
            World.PopulationProvide += info.PopulationProvide;
        }
コード例 #9
0
        private static void ApplyAttack(List <AttackTarget> targets, List <Entity> units, List <Entity> enemies, Dictionary <int, List <EntityTarget> > unitTargets)
        {
            foreach (AttackTarget target in targets)
            {
                Entity enemy = target.Enemy;
                Entity unit  = target.Unit;

                enemy.AcceptedDamage += unit.AttackDamage;
                if (enemy.AcceptedDamage >= enemy.Health)
                {
                    enemies.Remove(enemy); // die on next tick

                    foreach (List <EntityTarget> tmp in unitTargets.Values)
                    {
                        tmp.RemoveAll(x => x.Entity.Id == enemy.Id);
                    }
                }

                unit.Action = Actions.Attack(enemy);
                units.Remove(unit);
            }

            targets.Clear();
        }
コード例 #10
0
 public void Add(Entity unit)
 {
     Units.Add(unit);
     Damage += unit.AttackDamage;
 }
コード例 #11
0
 public DamageMap(Entity enemy)
 {
     Enemy = enemy;
     Units = new List <Entity>();
 }
コード例 #12
0
 public AttackTarget(Entity unit, Entity enemy)
 {
     Unit  = unit;
     Enemy = enemy;
 }
コード例 #13
0
        private static bool IsFacility(Point point)
        {
            Entity entity = World.Get(point).Entity;

            return(entity != null && entity.Facility);
        }
コード例 #14
0
        public static void Build(List <Entity> builders, EntityType type)
        {
            EntityInfo info = World.Info[type];

            if (World.Money < info.Cost)
            {
                return; // no money
            }

            int    size        = info.Size;
            Entity bestBuilder = null;
            Point  bestSpawn   = new Point();
            int    minDistance = int.MaxValue;

            foreach (Entity builder in builders)
            {
                int x = builder.Position.X;
                int y = builder.Position.Y;

                for (int i = 0; i < size; i++)
                {
                    var left = new Point(x - size, y - i); // left side
                    if (CheckSpawn(type, left, size, ref minDistance, ref bestSpawn))
                    {
                        bestBuilder = builder;
                    }

                    var right = new Point(x + 1, y - i); // right side
                    if (CheckSpawn(type, right, size, ref minDistance, ref bestSpawn))
                    {
                        bestBuilder = builder;
                    }

                    var top = new Point(x - i, y + 1); // top side
                    if (CheckSpawn(type, top, size, ref minDistance, ref bestSpawn))
                    {
                        bestBuilder = builder;
                    }

                    var bottom = new Point(x - i, y - size); // bottom size
                    if (CheckSpawn(type, bottom, size, ref minDistance, ref bestSpawn))
                    {
                        bestBuilder = builder;
                    }
                }
            }

            if (bestBuilder == null)
            {
                return;
            }

            bestBuilder.Action = Actions.Build(type, bestSpawn);
            builders.Remove(bestBuilder);

            for (int x = bestSpawn.X; x < bestSpawn.X + size; x++)
            {
                for (int y = bestSpawn.Y; y < bestSpawn.Y + size; y++)
                {
                    World.Get(x, y).ReservedForEntity = bestBuilder;
                }
            }

            World.Money             -= info.Cost;
            World.PopulationProvide += info.PopulationProvide;
            World.PopulationUse     += info.PopulationUse;
        }