public void RangeTest()
        {
            Vec2Int p      = new Vec2Int(1, 1);
            var     radius = p.Range(1);

            Assert.True(radius.Count == 4);
        }
        public static void SetAttack(Entity entity, int attackRange, int size, Dictionary <int, EntityAction> entityActions)
        {
            if (entityActions.ContainsKey(entity.Id))
            {
                return;
            }

            if (entity.EntityType == EntityType.RangedUnit &&
                ScoreMap.Get(entity.Position).MeleeDamage > 0)
            {
                return;
            }

            List <Vec2Int> range = new List <Vec2Int>();

            if (size > 1)
            {
                for (int y = entity.Position.Y; y < entity.Position.Y + size; y++)
                {
                    for (int x = entity.Position.X; x < entity.Position.X + size; x++)
                    {
                        var position = new Vec2Int(x, y);
                        range.AddRange(position.Range(attackRange));
                    }
                }

                range = range.Distinct().ToList();
            }
            else
            {
                range = entity.Position.Range(attackRange);
            }

            var enemiesUnderAttack = new HashSet <Entity>();

            foreach (var position in range)
            {
                var cell = ScoreMap.Get(position);
                if (cell.Entity != null &&
                    cell.Entity?.EntityType != EntityType.Resource &&
                    cell.Entity?.PlayerId != ScoreMap.MyId &&
                    !enemiesUnderAttack.Contains(cell.Entity.Value))
                {
                    enemiesUnderAttack.Add(cell.Entity.Value);
                }
            }

            SetAttack(entity, EntityType.RangedUnit, 1, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.BuilderUnit, 1, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.MeleeUnit, 1, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.Turret, 2, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.RangedBase, 5, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.MeleeBase, 5, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.BuilderBase, 5, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.House, 3, enemiesUnderAttack, entityActions);
            SetAttack(entity, EntityType.Wall, 1, enemiesUnderAttack, entityActions);
        }
Example #3
0
        public static void InitMap(PlayerView playerView)
        {
            for (int y = 0; y < 80; y++)
            {
                for (int x = 0; x < 80; x++)
                {
                    var cell = Map[x, y];
                    cell.Entity        = null;
                    cell.ResourceScore = 0;
                    cell.RepairScore   = 0;
                    cell.MeleeAttack   = 0;
                    cell.RangedAttack  = 0;
                    cell.MeleeDamage   = 0;
                    cell.TurretDamage  = 0;
                    cell.RangedDamage  = 0;
                }
            }

            MyId       = playerView.MyId;
            MyResource = playerView.Players[MyId - 1].Resource;
            AnyRepairScoreMoreThanOne = false;

            MyProduction.Clear();
            EnemyTargets.Clear();

            BuilderUnitTargets.Clear();

            MyBuilderUnits.Clear();
            MyMeleeUnits.Clear();
            MyRangedUnits.Clear();

            MyActiveBuilderBases.Clear();
            MyNotActiveBuilderBases.Clear();

            MyActiveMeleeBases.Clear();
            MyNotActiveMeleeBases.Clear();

            MyActiveRangedBases.Clear();
            MyNotActiveRangedBases.Clear();

            MyActiveHouses.Clear();
            MyNotActiveHouses.Clear();

            MyActiveTurrets.Clear();
            MyNotActiveTurrets.Clear();

            BuilderUnitProperties = playerView.EntityProperties[EntityType.BuilderUnit];
            MeleeUnitProperties   = playerView.EntityProperties[EntityType.MeleeUnit];
            RangedUnitProperties  = playerView.EntityProperties[EntityType.RangedUnit];

            BuilderBaseProperties = playerView.EntityProperties[EntityType.BuilderBase];
            MeleeBaseProperties   = playerView.EntityProperties[EntityType.MeleeBase];
            RangedBaseProperties  = playerView.EntityProperties[EntityType.RangedBase];
            HouseProperties       = playerView.EntityProperties[EntityType.House];
            TurretProperties      = playerView.EntityProperties[EntityType.Turret];

            foreach (Entity entity in playerView.Entities)
            {
                var properties = playerView.EntityProperties[entity.EntityType];
                if (properties.Size > 1)
                {
                    for (int y = entity.Position.Y; y < entity.Position.Y + properties.Size; y++)
                    {
                        for (int x = entity.Position.X; x < entity.Position.X + properties.Size; x++)
                        {
                            Map[x, y].Entity = entity;
                        }
                    }
                }
                else
                {
                    Map[entity.Position.X, entity.Position.Y].Entity = entity;
                }
            }

            foreach (Entity entity in playerView.Entities)
            {
                var properties = playerView.EntityProperties[entity.EntityType];

                // collect resources
                if (entity.EntityType == EntityType.Resource)
                {
                    var neighbors = entity.Position.Neighbors();
                    foreach (var target in neighbors)
                    {
                        if (PassableInFuture(target))
                        {
                            Map[target.X, target.Y].ResourceScore += 1;
                        }
                    }
                }

                // enemy
                if (entity.PlayerId != MyId &&
                    entity.EntityType != EntityType.Resource &&
                    (entity.EntityType != EntityType.Turret || !entity.Active))
                {
                    EnemyTargets.Add(entity.Position);

                    var neighbors = entity.Position.Neighbors(properties.Size);
                    foreach (var target in neighbors)
                    {
                        if (PassableInFuture(target))
                        {
                            Map[target.X, target.Y].MeleeAttack = 1;
                        }
                    }

                    var range = entity.Position.Range(4, 3);
                    foreach (var target in range)
                    {
                        if (PassableInFuture(target))
                        {
                            Map[target.X, target.Y].RangedAttack = 1;
                        }
                    }
                }

                // my
                if (entity.PlayerId == MyId)
                {
                    // units
                    if (entity.EntityType == EntityType.BuilderUnit)
                    {
                        MyBuilderUnits.Add(entity);
                        MyProduction.Add(entity);
                    }

                    if (entity.EntityType == EntityType.MeleeUnit)
                    {
                        MyMeleeUnits.Add(entity);
                    }

                    if (entity.EntityType == EntityType.RangedUnit)
                    {
                        MyRangedUnits.Add(entity);
                    }

                    // buildings
                    if (entity.EntityType == EntityType.BuilderBase)
                    {
                        if (entity.Active)
                        {
                            MyActiveBuilderBases.Add(entity);
                        }
                        else
                        {
                            MyNotActiveBuilderBases.Add(entity);
                        }

                        MyProduction.Add(entity);
                    }

                    if (entity.EntityType == EntityType.MeleeBase)
                    {
                        if (entity.Active)
                        {
                            MyActiveMeleeBases.Add(entity);
                        }
                        else
                        {
                            MyNotActiveMeleeBases.Add(entity);
                        }

                        MyProduction.Add(entity);
                    }

                    if (entity.EntityType == EntityType.RangedBase)
                    {
                        if (entity.Active)
                        {
                            MyActiveRangedBases.Add(entity);
                        }
                        else
                        {
                            MyNotActiveRangedBases.Add(entity);
                        }

                        MyProduction.Add(entity);
                    }

                    if (entity.EntityType == EntityType.House)
                    {
                        if (entity.Active)
                        {
                            MyActiveHouses.Add(entity);
                        }
                        else
                        {
                            MyNotActiveHouses.Add(entity);
                        }

                        MyProduction.Add(entity);
                    }

                    if (entity.EntityType == EntityType.Turret)
                    {
                        if (entity.Active)
                        {
                            MyActiveTurrets.Add(entity);
                        }
                        else
                        {
                            MyNotActiveTurrets.Add(entity);
                        }
                    }

                    // repair
                    if (entity.Health < properties.MaxHealth &&
                        (entity.EntityType == EntityType.BuilderBase ||
                         entity.EntityType == EntityType.MeleeBase ||
                         entity.EntityType == EntityType.RangedBase ||
                         entity.EntityType == EntityType.House ||
                         entity.EntityType == EntityType.Turret))
                    {
                        var neighbors     = entity.Position.Neighbors(properties.Size);
                        var buildersCount = neighbors.Count(n => Get(n).Entity?.EntityType == EntityType.BuilderUnit);
                        foreach (var target in neighbors)
                        {
                            if (Passable(target))
                            {
                                Map[target.X, target.Y].RepairScore = entity.Active && buildersCount > 3 ? 1 : 2;
                                if (Map[target.X, target.Y].RepairScore == 2)
                                {
                                    AnyRepairScoreMoreThanOne = true;
                                }
                            }
                        }
                    }
                }
            }

            for (int y = 0; y < 80; y++)
            {
                for (int x = 0; x < 80; x++)
                {
                    if (Map[x, y].Entity == null)
                    {
                        continue;
                    }

                    Entity entity = Map[x, y].Entity.Value;

                    // check builders
                    if (entity.PlayerId == MyId &&
                        entity.EntityType == EntityType.BuilderUnit)
                    {
                        Map[entity.Position.X, entity.Position.Y].ResourceScore = 0;
                        Map[entity.Position.X, entity.Position.Y].RepairScore   = 0;
                    }

                    // check damage
                    if (entity.PlayerId != MyId &&
                        entity.EntityType == EntityType.MeleeUnit)
                    {
                        var range = entity.Position.Range(2);
                        foreach (var point in range)
                        {
                            Map[point.X, point.Y].MeleeDamage  += 10;
                            Map[point.X, point.Y].ResourceScore = 0;
                            Map[point.X, point.Y].RepairScore   = 0;
                        }
                    }

                    if (entity.PlayerId != MyId &&
                        entity.EntityType == EntityType.Turret &&
                        entity.Active)
                    {
                        var position = new Vec2Int(x, y);
                        var range    = position.Range(5);
                        foreach (var point in range)
                        {
                            var healthCoeff = entity.Health / 5;
                            Map[point.X, point.Y].TurretDamage += 10 * healthCoeff;
                            Map[point.X, point.Y].ResourceScore = 0;
                            Map[point.X, point.Y].RepairScore   = 0;
                        }
                    }

                    if (entity.PlayerId != MyId &&
                        entity.EntityType == EntityType.RangedUnit)
                    {
                        var range = entity.Position.Range(6);
                        foreach (var point in range)
                        {
                            Map[point.X, point.Y].RangedDamage += 10;
                            Map[point.X, point.Y].ResourceScore = 0;
                            Map[point.X, point.Y].RepairScore   = 0;
                        }
                    }
                }
            }

            // BuilderUnitTargets
            for (int y = 0; y < 80; y++)
            {
                for (int x = 0; x < 80; x++)
                {
                    var cell = Map[x, y];
                    if (cell.ResourceScore > 0 ||
                        cell.RepairScore > 0)
                    {
                        BuilderUnitTargets.Add(new Vec2Int(x, y));
                    }
                }
            }

            MyBuilderUnits = MyBuilderUnits
                             .OrderBy(e => e.Position.Distance(MyBase))
                             .ToList();

            Limit = MyBuilderUnits.Count +
                    MyMeleeUnits.Count +
                    MyRangedUnits.Count;

            AvailableLimit = (MyActiveBuilderBases.Count +
                              MyActiveMeleeBases.Count +
                              MyActiveRangedBases.Count +
                              MyActiveHouses.Count) * 5;
        }