public static void AppendEnemyPower(List <List <DbScanHelper.Point> > clusters, bool applyNuclearStrikePower)
        {
            var basePower = EnemyPowerToDodge;

            var currentSelectedGroup = GroupHelper.CurrentGroup;

            //Хак по задержке вертов при старте, тянемся к ифвам
            if (currentSelectedGroup.VehicleType == VehicleType.Helicopter && GlobalHelper.World.TickIndex < 800)
            {
                var ifvGroup = GroupHelper.Groups.FirstOrDefault(x => x.VehicleType == VehicleType.Ifv);
                if (ifvGroup != null)
                {
                    var ifvUnits = UnitHelper.UnitsAlly.Where(x => x.Groups.Contains(ifvGroup.Id)).ToArray();
                    var ifvX     = ifvUnits.Sum(x => x.X) / ifvUnits.Length;
                    var ifvY     = ifvUnits.Sum(x => x.Y) / ifvUnits.Length;

                    var eCellX = (int)ifvX / PpSize;
                    var eCellY = (int)ifvY / PpSize;

                    ApplyPower(PotentialFields, eCellX, eCellY, RangePowerMask49, -(float)ifvUnits.Length * basePower / 2);

                    return;
                }
            }

            var selectedUnits = UnitHelper.UnitsAlly.Where(x => x.Groups.Contains(GroupHelper.CurrentGroup.Id)).ToArray();
            var myGroupPower  = selectedUnits
                                .Sum(x => BattleHelper.GetPowerHealthMulitplier(currentSelectedGroup.VehicleType, x.Durability))
                                * basePower;

            var minEnemiesToAttack = NuclearStrikeHelper.GetMinEnemiesToAttackNuclearStrike();

            foreach (var enemies in clusters)
            {
                var ex     = enemies.Sum(x => x.X) / enemies.Count;
                var ey     = enemies.Sum(x => x.Y) / enemies.Count;
                var eCellX = (int)ex / PpSize;
                var eCellY = (int)ey / PpSize;

                var res = BattleHelper.CalculatePower(enemies, currentSelectedGroup.VehicleType, basePower);

                var enemyPower       = res.EnemyPower;
                var canAttackSomeone = res.CanAttackSomeone;

                //Если готовы нанести ядерный удар
                if (applyNuclearStrikePower)
                {
                    //И врагов в кластере достаточно для удара, сделаем врагов притягиваемыми
                    if (enemies.Count >= minEnemiesToAttack)
                    {
                        ApplyPower(PotentialFields, eCellX, eCellY, RangePowerMask49, -enemyPower);
                    }
                }
                else
                {
                    if (canAttackSomeone)
                    {
                        var pwr = enemyPower - myGroupPower;
                        if (pwr >= 0)
                        {
                            //Если атакуют вертов, попробуем укрыться за Ifv
                            if (currentSelectedGroup.VehicleType == VehicleType.Helicopter &&
                                enemies.Any(x => x.Type == VehicleType.Fighter) &&
                                pwr > 0)
                            {
                                var sx = selectedUnits.Sum(x => x.X) / selectedUnits.Length;
                                var sy = selectedUnits.Sum(x => x.Y) / selectedUnits.Length;

                                var distanceLow = GeometryHelper.GetDistancePower2To(sx, sy, ex, ey) < (300 * 300);

                                if (distanceLow)
                                {
                                    var ifvGroup = GroupHelper.Groups.FirstOrDefault(x => x.VehicleType == VehicleType.Ifv);
                                    if (ifvGroup != null)
                                    {
                                        var ifvUnits = UnitHelper.UnitsAlly.Where(x => x.Groups.Contains(ifvGroup.Id)).ToArray();
                                        var ifvX     = ifvUnits.Sum(x => x.X) / ifvUnits.Length;
                                        var ifvY     = ifvUnits.Sum(x => x.Y) / ifvUnits.Length;

                                        var ifvCellX = (int)ifvX / PpSize;
                                        var ifvCellY = (int)ifvY / PpSize;

                                        ApplyPower(PotentialFields, ifvCellX, ifvCellY, RangePowerMask49, -(float)ifvUnits.Length * basePower);
                                    }
                                }
                            }

                            ApplyPower(PotentialFields, eCellX, eCellY, RangePowerMask7, pwr);
                        }
                        else
                        {
                            ApplyPower(PotentialFields, eCellX, eCellY, RangePowerMask49, pwr);
                        }
                    }
                    else
                    {
                        ApplyPower(PotentialFields, eCellX, eCellY, RangePowerMask7, enemyPower);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private static bool NeedStopProduction(FacilityEx facility, MyLivingUnit[] createdUnassignedUnits)
        {
            var isProductionTickExceed = GlobalHelper.Game.TickCount - GlobalHelper.World.TickIndex <
                                         ConfigurationHelper.StopProductionWhenTicksToEndGameRemaining;

            //var testStopProduction = (GlobalHelper.World.TickIndex / 1000) % 2 == 1;

            //Остановим производство, если слишком много юнитов
            //Для варианта с туманом, если их больше n
            //Для варианта без тумана, если количество превышает кол-во врага в n раз
            var isUnitsTooMuch = (GlobalHelper.Mode == GameMode.FacFow
                                     ? UnitHelper.UnitsAlly.Length > 750
                                     : UnitHelper.UnitsAlly.Length - UnitHelper.UnitsEnemy.Length > 300) &&
                                 GlobalHelper.World.TickIndex > 10000;

            var clusters = MyStrategy.LazyClusters.Value;
            //var res = BattleHelper.CalculatePower(enemies, currentSelectedGroup.VehicleType, basePower);
            var isEnemyCanBeatProducingGroupTooClose = false;

            if (facility.Side == Side.Our && clusters.Count > 0 && createdUnassignedUnits.Length > 0)
            {
                var vehicleType = createdUnassignedUnits[0].Type;

                var basePower = PotentialFieldsHelper.EnemyPowerToDodge;

                var facilityUnitsX = createdUnassignedUnits.Sum(x => x.X) / createdUnassignedUnits.Length;
                var facilityUnitsY = createdUnassignedUnits.Sum(x => x.Y) / createdUnassignedUnits.Length;

                isEnemyCanBeatProducingGroupTooClose = clusters.Any(cluster =>
                {
                    var clusterUnitsX = cluster.Sum(x => x.X) / cluster.Count;
                    var clusterUnitsY = cluster.Sum(x => x.Y) / cluster.Count;

                    var isInRange =
                        GeometryHelper.GetDistancePower2To(facilityUnitsX, facilityUnitsY, clusterUnitsX, clusterUnitsY)
                        <= ConfigurationHelper.EnemyNearOurFacilityWarningRangePow2;

                    if (!isInRange)
                    {
                        return(false);
                    }

                    var res = BattleHelper.CalculatePower(cluster, vehicleType, PotentialFieldsHelper.EnemyPowerToDodge);

                    var enemyPower       = res.EnemyPower;
                    var canAttackSomeone = res.CanAttackSomeone;

                    var existGroupPower =
                        createdUnassignedUnits.Sum(y => BattleHelper.GetPowerHealthMulitplier(y.Type, y.Durability)) *
                        basePower;

                    bool needStayOnFacility;

                    //Если строящаяся группа сильнее или чуть чуть слабее, то не уходим
                    if (existGroupPower * 1.2 > enemyPower)
                    {
                        needStayOnFacility = true;
                        //needStayOnFacility = canAttackSomeone;
                    }
                    else
                    {
                        //Если у врага нулевая сила, никуда не уходим
                        needStayOnFacility = (Math.Abs(enemyPower) < PotentialFieldsHelper.Epsilon);
                    }

                    return(!needStayOnFacility);
                });
            }

            var result = isProductionTickExceed || isUnitsTooMuch || isEnemyCanBeatProducingGroupTooClose /*|| testStopProduction*/;

            if (result)
            {
                var a = 0;
            }

            return(result);
        }
        private static StartProductionParams GetStartProductionParams(List <List <DbScanHelper.Point> > clusters)
        {
            if (clusters.Count == 0)
            {
                return(new StartProductionParams(VehicleType.Tank, MaxCountToCreate));
            }

            var clustersOrder = clusters.OrderByDescending(x => x.Count).ToList();

            var productionVehicleTypes = new[]
            {
                VehicleType.Tank,
                VehicleType.Ifv,
                VehicleType.Helicopter,
                VehicleType.Fighter
            };

            var basePower = PotentialFieldsHelper.EnemyPowerToDodge;

            foreach (var cluster in clustersOrder)
            {
                foreach (var productionVehicleType in productionVehicleTypes)
                {
                    var res = BattleHelper.CalculatePower(cluster, productionVehicleType, basePower);
                    if (!res.CanAttackSomeone)
                    {
                        continue;
                    }

                    //Если уже производится отряд сильнее или есть, то не делаем еще раз такойже
                    var currentGroupsOfType = GroupHelper.Groups.Where(x => x.VehicleType == productionVehicleType)
                                              .ToArray();

                    var anyExistGroupStronger = currentGroupsOfType.Any(x =>
                    {
                        var groupUnits      = UnitHelper.UnitsAlly.Where(y => y.Groups.Contains(x.Id)).ToArray();
                        var existGroupPower =
                            groupUnits.Sum(y => BattleHelper.GetPowerHealthMulitplier(x.VehicleType, y.Durability)) *
                            basePower;
                        return(existGroupPower > res.EnemyPower);
                    });

                    if (anyExistGroupStronger)
                    {
                        continue;
                    }

                    var producingFactories = FacilityHelper.Facilities.Select(x => x.Value)
                                             .Where(x => x.Side == Side.Our)
                                             .Where(x => x.Type == FacilityType.VehicleFactory)
                                             .Where(x => x.VehicleType != null && x.VehicleType == productionVehicleType)
                                             .ToArray();

                    var isAnyProducingStronger = producingFactories.Any(x =>
                    {
                        var facPower = x.ProductionCount * basePower;
                        return(facPower > res.EnemyPower);
                    });

                    if (isAnyProducingStronger)
                    {
                        continue;
                    }

                    //Нельзя произвести юнитов сильнее отряда
                    if (res.EnemyPower > MaxCountToCreate * basePower)
                    {
                        continue;
                    }

                    if (Math.Abs(res.EnemyPower) < PotentialFieldsHelper.Epsilon)
                    {
                        return(new StartProductionParams(productionVehicleType, MaxCountToCreate / 2));
                    }

                    var powerToCreate = res.EnemyPower * 1.2;
                    var count         = (int)(powerToCreate / basePower);

                    if (count > MaxCountToCreate)
                    {
                        count = MaxCountToCreate;
                    }

                    return(new StartProductionParams(productionVehicleType, count));
                }
            }

            return(new StartProductionParams(VehicleType.Tank, MaxCountToCreate));
        }