예제 #1
0
        public static void Update()
        {
            _disappearedIds.Clear();
            foreach (Vehicle vehicle in MyStrategy.World.NewVehicles)
            {
                _vehicleById[vehicle.Id] = vehicle;
                VehicleById[vehicle.Id]  = new AVehicle(vehicle);

                if (G.IsFogOfWarEnabled && vehicle.PlayerId != MyStrategy.Me.Id)
                {
                    if (vehicle.Id <= 1000 && !_visibleOnce.Contains(vehicle.Id))
                    {
                        var fakeId = _idsPool[(int)vehicle.Type].Last();
                        _idsPool[(int)vehicle.Type].Pop();

                        OppUncheckedVehicles.Remove(fakeId);
                        OppCheckedVehicles.Remove(fakeId);
                    }

                    OppCheckedVehicles.Remove(vehicle.Id);
                    OppUncheckedVehicles.Remove(vehicle.Id);

                    _visibleOnce.Add(vehicle.Id);
                }
            }

            foreach (VehicleUpdate vehicleUpdate in MyStrategy.World.VehicleUpdates)
            {
                var vehicleId = vehicleUpdate.Id;

                if (vehicleUpdate.Durability == 0)
                {
                    _vehicleById.Remove(vehicleId);
                    VehicleById.Remove(vehicleId);

                    _disappearedIds.Add(vehicleId);
                }
                else
                {
                    var veh = new Vehicle(_vehicleById[vehicleId], vehicleUpdate);
                    _vehicleById[vehicleId] = veh;
                    if (veh.PlayerId != MyStrategy.Me.Id)
                    {
                        OppCheckedVehicles.Remove(veh.Id);
                        OppUncheckedVehicles.Remove(veh.Id);
                    }
                }
            }

            var errorsCount = 0;

            foreach (var veh in _vehicleById.Values)
            {
                var prev = MoveObserver.BeforeMoveUnits.ContainsKey(veh.Id) ? MoveObserver.BeforeMoveUnits[veh.Id] : null;
                var cur  = VehicleById.ContainsKey(veh.Id) ? VehicleById[veh.Id] : null;

                var updatedVehicle = new AVehicle(veh);

                if (updatedVehicle.IsMy)
                {
                    if (prev != null)
                    {
                        AVehicle aveh = new AVehicle(prev);
                        if (!Geom.PointsEquals(prev, updatedVehicle)) // в local runner сдвинулся
                        {
                            aveh.Move();
                        }
                        if (!Geom.PointsEquals(aveh, updatedVehicle))
                        {
                            Console.WriteLine("Looks vehicle updated wrong (X, Y)");
                        }

                        if ((aveh.Action == AVehicle.MoveType.Move || aveh.Action == AVehicle.MoveType.Scale) && Geom.DoublesEquals(aveh.MoveLengthOrRotationAngle, 0) ||
                            aveh.Action == AVehicle.MoveType.Rotate && Geom.DoublesEquals(aveh.MoveLengthOrRotationAngle, 0))
                        {
                            aveh.ForgotTarget();
                        }
                        updatedVehicle.Action = aveh.Action;
                        updatedVehicle.MoveVectorOrRotationCenter = aveh.MoveVectorOrRotationCenter;
                        updatedVehicle.MoveSpeedOrAngularSpeed    = aveh.MoveSpeedOrAngularSpeed;
                        updatedVehicle.MoveLengthOrRotationAngle  = aveh.MoveLengthOrRotationAngle;
                        updatedVehicle.DurabilityPool             = cur.DurabilityPool;
                        //TODO: поддерживать DurabilityPool if (!updatedVehicle.IsMy)
                    }

                    // дополнительные проверки
                    if (prev != null && !Geom.PointsEquals(prev, updatedVehicle)) // в local runner сдвинулся
                    {
                        var tmp = new AVehicle(cur);
                        if (Geom.PointsEquals(prev, cur))
                        {
                            tmp = new AVehicle(prev);
                            tmp.Move();
                            errorsCount++;
                        }

                        if (!Geom.PointsEquals(tmp, updatedVehicle))
                        {
                            Console.WriteLine("Looks vehicle updated wrong (X, Y)");
                        }
                    }
                    else if (!Geom.PointsEquals(cur, updatedVehicle)) // мой сдвинулся, а в local runner нет
                    {
                        errorsCount++;
                        var tmp = new AVehicle(updatedVehicle);
                        tmp.Move();
                        if (!Geom.PointsEquals(cur, tmp))
                        {
                            Console.WriteLine("Looks vehicle updated wrong (X, Y)");
                        }
                    }
                }

                VehicleById[veh.Id] = updatedVehicle;


                if (cur != null && updatedVehicle.IsSelected != cur.IsSelected)
                {
                    Console.WriteLine("Looks vehicle updated wrong (IsSelected)");
                }
            }

            if (errorsCount > 0)
            {
                Logger.Log("Move errors count: " + errorsCount);
            }
        }
예제 #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));
        }