public static DangerResult GetDanger(Sandbox startEnv, Sandbox env, List <MyGroup> myGroups, List <VehiclesCluster> myUngroups, double sumMaxAlmostAttacksCache = -1) { ExpB = Math.Log(ExpY1 / ExpY2) / (ExpX2 - ExpX1); ExpA = ExpY1 / Math.Exp(-ExpB * ExpX1); Logger.CumulativeOperationStart("GetDanger"); var result = new DangerResult(); if (sumMaxAlmostAttacksCache <= -1) { result.SumMaxAlmostAttacks = GetSumMaxAlmostAttacks(env, env.MyVehicles); } else { result.SumMaxAlmostAttacks = sumMaxAlmostAttacksCache; } Logger.CumulativeOperationStart("Danger1"); var myDurabilityBefore = startEnv.MyVehicles.Sum(x => x.FullDurability); var oppDurabilityBefore = startEnv.OppVehicles.Sum(x => x.FullDurability); var myDurabilityAfter = env.MyVehicles.Sum(x => x.FullDurability); var oppDurabilityAfter = env.OppVehicles.Sum(x => x.FullDurability); result.MyDurabilityDiff = myDurabilityBefore - myDurabilityAfter; result.OppDurabilityDiff = oppDurabilityBefore - oppDurabilityAfter; result.MyDeadsCount = env.MyVehicles.Count(x => !x.IsAlive); result.OppDeadsCount = env.OppVehicles.Count(x => !x.IsAlive); result.FacilitiesPointsDiff = startEnv.Facilities.Sum(x => x.CapturePoints) - env.Facilities.Sum(x => x.CapturePoints); // nuclears foreach (var nuclear in env.Nuclears) { foreach (var target in env.GetAllNeighbours(nuclear.X, nuclear.Y, nuclear.Radius)) { result.NuclearsPotentialDamage += Utility.TrueFactor(target.IsMy) * target.GetNuclearDamage(nuclear); } } // groups intersections var groupsIsAerial = myGroups.Select(g => Utility.IsAerial(g.VehicleType)) .Concat(myUngroups.Select(cl => cl[0].IsAerial)) .ToArray(); var groupsRects = myGroups.Select(g => Utility.BoundingRect(env.GetVehicles(true, g))) .Concat(myUngroups.Select(cl => cl.BoundingRect)) .ToArray(); for (var j = 0; j < groupsRects.Length; j++) { var rect = groupsRects[j]; if (rect.X < G.VehicleRadius || rect.Y < G.VehicleRadius || rect.X + G.VehicleRadius > G.MapSize || rect.Y + G.VehicleRadius > G.MapSize) { result.RectanglesIntersects1++; continue; } for (var i = 0; i < j; i++) { if (groupsIsAerial[i] != groupsIsAerial[j]) { continue; } var rect1 = groupsRects[i].Clone(); var rect2 = groupsRects[j].Clone(); rect1.ExtendRadius(G.VehicleRadius * 1.5); rect2.ExtendRadius(G.VehicleRadius * 1.5); if (rect1.IntersectsWith(rect2)) { result.RectanglesIntersects1++; continue; } rect1.ExtendRadius(G.VehicleRadius * 1.5); rect2.ExtendRadius(G.VehicleRadius * 1.5); if (rect1.IntersectsWith(rect2)) { result.RectanglesIntersects2++; } } } Logger.CumulativeOperationEnd("Danger1"); var clusters = OppClusters; // NOTE: юниты врага считаются неподвижными, поэтому берем инстансы из основного Environment Logger.CumulativeOperationStart("Danger2"); var groundGroupsCenters = new List <Point>(); var groundGroups = new List <List <AVehicle> >(); var groundGroupsIdxes = new List <int>(); var groundGroupsId = new List <MyGroup>(); for (var s = 0; s < myGroups.Count + myUngroups.Count; s++) { VehicleType type; MyGroup gr = null; List <AVehicle> myGroup; if (s < myGroups.Count) { gr = myGroups[s]; type = gr.VehicleType; myGroup = env.GetVehicles(true, gr); } else { myGroup = myUngroups[s - myGroups.Count]; type = myGroup[0].Type; } var myGroupCenter = Utility.Average(myGroup); var list = new List <DangerResult.ScoreDistancePair>(); var myRatio = 1.0 * myGroup.Count / env.MyVehicles.Count; foreach (var cl in clusters) { for (var oppType = 0; oppType < 5; oppType++) { if (cl.CountByType[oppType] == 0) { continue; } var myAttack = G.AttackDamage[(int)type, oppType]; var oppAttack = G.AttackDamage[oppType, (int)type]; var avg = Utility.Average(cl.VehicleType((VehicleType)oppType)); var dist = avg.GetDistanceTo(myGroupCenter); var score = myAttack - oppAttack * 0.49; if (type == VehicleType.Helicopter && oppType == (int)VehicleType.Fighter) { score *= 2.5; } else if (type == VehicleType.Helicopter && oppType == (int)VehicleType.Arrv) { score *= 0.8; } var maxDurability = cl.CountByType[oppType] * G.MaxDurability; var durabilityCoeff = (maxDurability - cl.DurabilitySumByType[oppType]) / G.MaxDurability; if (score < 0) { durabilityCoeff *= -1; } score = score * (cl.CountByType[oppType] + durabilityCoeff) * myRatio; var e = -(myAttack == 0 && dist > 100 || myAttack <oppAttack && dist> (type == VehicleType.Helicopter ? 350 : 140) ? 0 : DangerExp(dist)); list.Add(new DangerResult.ScoreDistancePair(score, e)); } } foreach (var helpGroup in myGroups) { if (type == VehicleType.Helicopter && helpGroup.VehicleType == VehicleType.Ifv) { var fightersCount = env.GetVehicles(false, VehicleType.Fighter).Count; if (fightersCount == 0) { continue; } var helpGroupVehicles = env.GetVehicles(true, helpGroup); var helpGroupVehiclesCenter = Utility.BoundingRect(helpGroupVehicles).Center; var myAttack = G.AttackDamage[(int)type, (int)VehicleType.Fighter]; var oppAttack = G.AttackDamage[(int)VehicleType.Fighter, (int)type]; var score = (myAttack - oppAttack * 0.49) * 2.5; score = score * fightersCount * myRatio; var dist = myGroupCenter.GetDistanceTo(helpGroupVehiclesCenter); var distToFighter = Math.Sqrt(env.GetVehicles(false, VehicleType.Fighter).Min(x => x.GetDistanceTo2(myGroupCenter))); const double n = 400; var coef = Math.Max(0, (n - distToFighter) / n); list.Add(new DangerResult.ScoreDistancePair(coef * score, DangerExp(dist))); } if ((type == VehicleType.Helicopter || type == VehicleType.Fighter) && helpGroup.VehicleType == VehicleType.Arrv) { var helpGroupVehicles = env.GetVehicles(true, helpGroup); var helpGroupVehiclesCenter = Utility.BoundingRect(helpGroupVehicles).Center; var score = -(myGroup.Count * G.MaxDurability - myGroup.Sum(x => x.Durability)) * myRatio; var dist = myGroupCenter.GetDistanceTo(helpGroupVehiclesCenter); list.Add(new DangerResult.ScoreDistancePair(score, DangerExp(dist))); } } result.MoveToInfo.Add(new Tuple <MyGroup, int, List <DangerResult.ScoreDistancePair> >(gr, s, list)); // scale groups var boundingRect = Utility.BoundingRect(myGroup); boundingRect.ExtendRadius(G.VehicleRadius); result.RectanglesAreas.Add(new Tuple <double, int>(boundingRect.Area, myGroup.Count)); if (!Utility.IsAerial(type) && s < myGroups.Count) { groundGroups.Add(myGroup); groundGroupsCenters.Add(myGroupCenter); groundGroupsId.Add(gr); groundGroupsIdxes.Add(s); } } var targetFacilities = env.Facilities.Where(x => !x.IsMy).ToArray(); if (groundGroups.Count > 0 && targetFacilities.Length > 0) { var mat = new double[groundGroups.Count][]; for (var i = 0; i < groundGroups.Count; i++) { mat[i] = new double[targetFacilities.Length]; for (var j = 0; j < targetFacilities.Length; j++) { mat[i][j] = groundGroupsCenters[i].GetDistanceTo(targetFacilities[j].Center); } } var asg = HungarianAssignment.Minimize(mat, 2 * G.MapSize); for (var i = 0; i < groundGroups.Count; i++) { var myGroup = groundGroups[i]; var cen = groundGroupsCenters[i]; var myRatio = 1.0 * myGroup.Count / env.MyVehicles.Count; var flist = new List <DangerResult.ScoreDistancePair>(); if (asg[i] == -1) { continue; } var facility = targetFacilities[asg[i]]; result.TargetFacility[groundGroupsId[i].Group] = facility.Center; var dist = cen.GetDistanceTo(facility.Center); var score = -myRatio * (groundGroupsId[i].VehicleType == VehicleType.Arrv ? 4 : 1); flist.Add(new DangerResult.ScoreDistancePair(score, DangerExp(dist))); result.MoveToFacilitiesInfo.Add(new Tuple <MyGroup, int, List <DangerResult.ScoreDistancePair> >(groundGroupsId[i], groundGroupsIdxes[i], flist)); } } Logger.CumulativeOperationEnd("Danger2"); Logger.CumulativeOperationEnd("GetDanger"); return(result); }
public static void Initialize(World world, Game game) { if (world.TickIndex != 0) { return; } var hungTest = HungarianAssignment.Minimize(new double[3][] { new [] { 3.0, 10 }, new [] { 10.0, 2 }, new [] { 1.0, 10 }, }, 2 * G.MapSize); _expect(hungTest[0], -1); _expect(hungTest[1], 1); _expect(hungTest[2], 0); G.IsTopLeftStartingPosition = world.Players.Any(x => x.IsMe && x.Id == 1); _expect(world.Width, G.MapSize); _expect(world.Height, G.MapSize); _expect(game.ArrvDurability, G.MaxDurability); _expect(game.FighterDurability, G.MaxDurability); _expect(game.HelicopterDurability, G.MaxDurability); _expect(game.IfvDurability, G.MaxDurability); _expect(game.TankDurability, G.MaxDurability); _expect(game.CloudWeatherSpeedFactor, G.CloudWeatherSpeedFactor); _expect(game.RainWeatherSpeedFactor, G.RainWeatherSpeedFactor); _expect(game.SwampTerrainSpeedFactor, G.SwampTerrainSpeedFactor); _expect(game.ForestTerrainSpeedFactor, G.ForestTerrainSpeedFactor); const int arrv = (int)VehicleType.Arrv, fighter = (int)VehicleType.Fighter, helicopter = (int)VehicleType.Helicopter, ifv = (int)VehicleType.Ifv, tank = (int)VehicleType.Tank; _expect(Math.Max(0, game.FighterGroundDamage - game.ArrvAerialDefence), G.AttackDamage[fighter, arrv]); _expect(Math.Max(0, game.FighterAerialDamage - game.FighterAerialDefence), G.AttackDamage[fighter, fighter]); _expect(Math.Max(0, game.FighterAerialDamage - game.HelicopterAerialDefence), G.AttackDamage[fighter, helicopter]); _expect(Math.Max(0, game.FighterGroundDamage - game.IfvAerialDefence), G.AttackDamage[fighter, ifv]); _expect(Math.Max(0, game.FighterGroundDamage - game.TankAerialDefence), G.AttackDamage[fighter, tank]); _expect(Math.Max(0, game.HelicopterGroundDamage - game.ArrvAerialDefence), G.AttackDamage[helicopter, arrv]); _expect(Math.Max(0, game.HelicopterAerialDamage - game.FighterAerialDefence), G.AttackDamage[helicopter, fighter]); _expect(Math.Max(0, game.HelicopterAerialDamage - game.HelicopterAerialDefence), G.AttackDamage[helicopter, helicopter]); _expect(Math.Max(0, game.HelicopterGroundDamage - game.IfvAerialDefence), G.AttackDamage[helicopter, ifv]); _expect(Math.Max(0, game.HelicopterGroundDamage - game.TankAerialDefence), G.AttackDamage[helicopter, tank]); _expect(Math.Max(0, game.IfvGroundDamage - game.ArrvGroundDefence), G.AttackDamage[ifv, arrv]); _expect(Math.Max(0, game.IfvAerialDamage - game.FighterGroundDefence), G.AttackDamage[ifv, fighter]); _expect(Math.Max(0, game.IfvAerialDamage - game.HelicopterGroundDefence), G.AttackDamage[ifv, helicopter]); _expect(Math.Max(0, game.IfvGroundDamage - game.IfvGroundDefence), G.AttackDamage[ifv, ifv]); _expect(Math.Max(0, game.IfvGroundDamage - game.TankGroundDefence), G.AttackDamage[ifv, tank]); _expect(Math.Max(0, game.TankGroundDamage - game.ArrvGroundDefence), G.AttackDamage[tank, arrv]); _expect(Math.Max(0, game.TankAerialDamage - game.FighterGroundDefence), G.AttackDamage[tank, fighter]); _expect(Math.Max(0, game.TankAerialDamage - game.HelicopterGroundDefence), G.AttackDamage[tank, helicopter]); _expect(Math.Max(0, game.TankGroundDamage - game.IfvGroundDefence), G.AttackDamage[tank, ifv]); _expect(Math.Max(0, game.TankGroundDamage - game.TankGroundDefence), G.AttackDamage[tank, tank]); _expect(game.FighterGroundAttackRange, G.AttackRange[fighter, arrv]); _expect(game.FighterAerialAttackRange, G.AttackRange[fighter, fighter]); _expect(game.FighterAerialAttackRange, G.AttackRange[fighter, helicopter]); _expect(game.FighterGroundAttackRange, G.AttackRange[fighter, ifv]); _expect(game.FighterGroundAttackRange, G.AttackRange[fighter, tank]); _expect(game.HelicopterGroundAttackRange, G.AttackRange[helicopter, arrv]); _expect(game.HelicopterAerialAttackRange, G.AttackRange[helicopter, fighter]); _expect(game.HelicopterAerialAttackRange, G.AttackRange[helicopter, helicopter]); _expect(game.HelicopterGroundAttackRange, G.AttackRange[helicopter, ifv]); _expect(game.HelicopterGroundAttackRange, G.AttackRange[helicopter, tank]); _expect(game.IfvGroundAttackRange, G.AttackRange[ifv, arrv]); _expect(game.IfvAerialAttackRange, G.AttackRange[ifv, fighter]); _expect(game.IfvAerialAttackRange, G.AttackRange[ifv, helicopter]); _expect(game.IfvGroundAttackRange, G.AttackRange[ifv, ifv]); _expect(game.IfvGroundAttackRange, G.AttackRange[ifv, tank]); _expect(game.TankGroundAttackRange, G.AttackRange[tank, arrv]); _expect(game.TankAerialAttackRange, G.AttackRange[tank, fighter]); _expect(game.TankAerialAttackRange, G.AttackRange[tank, helicopter]); _expect(game.TankGroundAttackRange, G.AttackRange[tank, ifv]); _expect(game.TankGroundAttackRange, G.AttackRange[tank, tank]); _expect(game.FighterAttackCooldownTicks, G.AttackCooldownTicks); _expect(game.HelicopterAttackCooldownTicks, G.AttackCooldownTicks); _expect(game.IfvAttackCooldownTicks, G.AttackCooldownTicks); _expect(game.TankAttackCooldownTicks, G.AttackCooldownTicks); _expect(game.VehicleRadius, G.VehicleRadius); foreach (var a in G.AttackRange) { _expect(true, a <= G.MaxAttackRange); } _expect(1, game.ArrvRepairSpeed * G.ArrvRepairPoints); _expect(game.ArrvRepairRange, G.ArrvRepairRange); _expect(game.TacticalNuclearStrikeRadius, G.TacticalNuclearStrikeRadius); _expect(game.TacticalNuclearStrikeDelay, G.TacticalNuclearStrikeDelay); _expect(game.MaxTacticalNuclearStrikeDamage, G.MaxTacticalNuclearStrikeDamage); _expect(game.CloudWeatherVisionFactor, G.CloudWeatherVisionFactor); _expect(game.ForestTerrainVisionFactor, G.ForestTerrainVisionFactor); _expect(game.RainWeatherVisionFactor, G.RainWeatherVisionFactor); _expect(game.SwampTerrainVisionFactor, 1); _expect(game.ActionDetectionInterval, G.ActionDetectionInterval); _expect(game.BaseActionCount, G.BaseActionCount); _expect(game.AdditionalActionCountPerControlCenter, G.AdditionalActionCountPerControlCenter); _expect(game.ArrvSpeed, G.MaxSpeed[arrv]); _expect(game.FighterSpeed, G.MaxSpeed[fighter]); _expect(game.HelicopterSpeed, G.MaxSpeed[helicopter]); _expect(game.IfvSpeed, G.MaxSpeed[ifv]); _expect(game.TankSpeed, G.MaxSpeed[tank]); _expect(game.ArrvVisionRange, G.VisionRange[arrv]); _expect(game.FighterVisionRange, G.VisionRange[fighter]); _expect(game.HelicopterVisionRange, G.VisionRange[helicopter]); _expect(game.IfvVisionRange, G.VisionRange[ifv]); _expect(game.TankVisionRange, G.VisionRange[tank]); _expect(G.MaxSpeed.Max(), G.MaxVehicleSpeed); _expect(game.FacilityHeight, G.FacilitySize); _expect(game.FacilityWidth, G.FacilitySize); _expect(game.MaxFacilityCapturePoints, G.MaxFacilityCapturePoints); _expect(game.FacilityCapturePointsPerVehiclePerTick, G.FacilityCapturePointsPerVehiclePerTick); _expect(game.MaxUnitGroup, G.MaxUnitGroup); _expect(game.RainWeatherStealthFactor, G.RainWeatherStealthFactor); _expect(game.CloudWeatherStealthFactor, G.CloudWeatherStealthFactor); _expect(game.ForestTerrainStealthFactor, G.ForestTerrainStealthFactor); _expect(game.SwampTerrainStealthFactor, 1); _expect(game.ClearWeatherStealthFactor, 1); _expect(game.PlainTerrainStealthFactor, 1); _expect(game.ArrvProductionCost, G.ProductionCost[arrv]); _expect(game.FighterProductionCost, G.ProductionCost[fighter]); _expect(game.HelicopterProductionCost, G.ProductionCost[helicopter]); _expect(game.IfvProductionCost, G.ProductionCost[ifv]); _expect(game.TankProductionCost, G.ProductionCost[tank]); G.IsFacilitiesEnabled = world.Facilities.Length > 0; G.IsFogOfWarEnabled = game.IsFogOfWarEnabled; MixArrvsWithGrounds = !G.IsFacilitiesEnabled; }