Ejemplo n.º 1
0
        static double GetSumMaxAlmostAttacks(Sandbox env, IEnumerable <AVehicle> myVehicles)
        {
            Logger.CumulativeOperationStart("Danger0");
            var result = myVehicles.Sum(m =>
            {
                var additionalRadius   = m.ActualSpeed;
                const int radiusFactor = 5;
                return(env.GetOpponentNeighbours(m.X, m.Y, G.MaxAttackRange + additionalRadius * radiusFactor).DefaultIfEmpty(null)
                       .Max(opp =>
                {
                    if (opp == null)
                    {
                        return 0;
                    }
                    var dmg = opp.GetAttackDamage(m, additionalRadius * radiusFactor);
                    if (dmg == 0)
                    {
                        return
                        -(m.GetAttackDamage(opp, additionalRadius) +
                          m.GetAttackDamage(opp, additionalRadius * radiusFactor) / 2.0);
                    }
                    return (opp.GetAttackDamage(m, additionalRadius) +
                            opp.GetAttackDamage(m, additionalRadius * 2) / 2.0 +
                            opp.GetAttackDamage(m, additionalRadius * 3) / 4.0 +
                            opp.GetAttackDamage(m, additionalRadius * 4) / 8.0 +
                            dmg / 16.0
                            ) *
                    (G.AttackDamage[(int)m.Type, (int)opp.Type] > 0
                                   ? Geom.Sqr(1.0 * opp.Durability / G.MaxDurability)
                                   : 1) *
                    (m.Type == opp.Type ? 0.6 : 1) *
                    (G.IsAerialButerDetected && opp.Type == VehicleType.Fighter ? 3 : 1);
                }));
            });

            Logger.CumulativeOperationEnd("Danger0");
            return(result);
        }
Ejemplo n.º 2
0
        private Tuple <double, AMove> _nuclearFindMove(Sandbox env, double selTotalDamage, bool checkOnly)
        {
            AMove selMove = null;

            for (var s = 0; s < GroupsManager.MyGroups.Count + MyUngroupedClusters.Count; s++)
            {
                var vehicles = s < GroupsManager.MyGroups.Count
                    ? env.GetVehicles(true, GroupsManager.MyGroups[s])
                    : MyUngroupedClusters[s - GroupsManager.MyGroups.Count];
                var myAvg = Utility.Average(vehicles);

                var vrg = G.VisionRange[(int)VehicleType.Fighter] + G.MaxTacticalNuclearStrikeDamage;

                var oppGroups = OppClusters
                                .Where(cl =>
                                       cl.Avg.GetDistanceTo(myAvg) < vrg &&
                                       cl.Any(x => env.VehicleById.ContainsKey(x.Id)))// пропускать полностью фантомные группы
                                .OrderBy(cl => cl.Avg.GetDistanceTo(myAvg))
                                .Take(3)
                                .ToArray();

                foreach (var veh in vehicles)
                {
                    if (!veh.IsSelected && MoveObserver.AvailableActions < 3)
                    {
                        continue;
                    }
                    if (veh.IsSelected && MoveObserver.AvailableActions < 2)
                    {
                        continue;
                    }

                    var vr = veh.ActualVisionRange * 0.9;

                    foreach (
                        var oppGroup in
                        new[] { env.GetOpponentNeighbours(veh.X, veh.Y, vr + G.TacticalNuclearStrikeRadius) }.Concat(oppGroups))
                    {
                        ANuclear nuclear;
                        var      totalDamage = _nuclearGetDamage(veh, env, selTotalDamage, oppGroup, out nuclear);

                        if (totalDamage <= selTotalDamage)
                        {
                            continue;
                        }

                        var vehNextMove = new AVehicle(veh);
                        for (var t = 0; t < 3; t++)
                        {
                            vehNextMove.Move();
                        }
                        if (vehNextMove.GetDistanceTo2(nuclear) + Const.Eps >= Geom.Sqr(vehNextMove.ActualVisionRange))
                        {
                            continue;
                        }

                        const int n = 10;
                        if (vehicles.Count > n)
                        {
                            var myDist2        = veh.GetDistanceTo2(nuclear);
                            var myNearestCount = vehicles.Count(x => x.GetDistanceTo2(nuclear) <= myDist2);
                            if (myNearestCount < n)
                            {
                                continue;
                            }
                        }

                        selTotalDamage = totalDamage;
                        selMove        = new AMove
                        {
                            Action    = ActionType.TacticalNuclearStrike,
                            VehicleId = veh.Id,
                            Point     = nuclear,
                        };

                        if (checkOnly)
                        {
                            return(new Tuple <double, AMove>(selTotalDamage, selMove));
                        }
                    }
                }
            }

            if (selMove == null)
            {
                return(null);
            }

            return(new Tuple <double, AMove>(selTotalDamage, selMove));
        }