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