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); } } } }
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)); }