Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
        }