public void Charge(AVehicle veh) { if (!veh.CanChargeFacility) { return; } if (veh.IsMy) { if (CapturePoints < G.MaxFacilityCapturePoints && ContainsPoint(veh)) { CapturePoints += G.FacilityCapturePointsPerVehiclePerTick; if (CapturePoints > G.MaxFacilityCapturePoints) { CapturePoints = G.MaxFacilityCapturePoints; } } } else { if (CapturePoints > -G.MaxFacilityCapturePoints && ContainsPoint(veh)) { CapturePoints -= G.FacilityCapturePointsPerVehiclePerTick; if (CapturePoints < -G.MaxFacilityCapturePoints) { CapturePoints = -G.MaxFacilityCapturePoints; } } } }
public void UpdateVehicle(AVehicle cur, AVehicle from) { var prevX = cur.X; var prevY = cur.Y; cur.CopyFrom(from); _updateVehicleCoordinates(cur, prevX, prevY); }
public void CopyFrom(AVehicle unit) { Radius = unit.Radius; X = unit.X; Y = unit.Y; Id = unit.Id; _copyFrom(unit); }
public int GetAttackDamage2(AVehicle veh, double additionalRadius = 0) { var attackRange = Geom.Sqr(G.AttackRange[(int)Type, (int)veh.Type] + additionalRadius); if (GetDistanceTo2(veh) - Const.Eps > attackRange) { return(0); } return(G.AttackDamage[(int)Type, (int)veh.Type]); }
public int GetAttackDamage(AVehicle veh, double additionalRadius = 0) { var damage = GetAttackDamage2(veh, additionalRadius); if (damage >= veh.Durability) { return(veh.Durability); } return(damage); }
private static bool _isVehicleVisible(Sandbox env, AVehicle veh) { foreach (var x in env.GetMyNeighbours(veh.X, veh.Y, 120 * veh.StealthFactor)) { if (x.IsVisible(veh)) { return(true); } } return(false); }
public void Attack(AVehicle veh) { if (RemainingAttackCooldownTicks > 0) { return; } var damage = GetAttackDamage(veh); veh.Durability -= damage; RemainingAttackCooldownTicks = G.AttackCooldownTicks; }
private static void _fillStartingPosition(IEnumerable <AVehicle> myVehicles) { foreach (var my in myVehicles) { var clone = new AVehicle(my); clone.X = G.MapSize - clone.X; clone.Y = G.MapSize - clone.Y; clone.IsMy = !clone.IsMy; clone.Id *= -1; OppUncheckedVehicles[clone.Id] = clone; _idsPool[(int)clone.Type].Add(clone.Id); } }
public void AddVehicleGroup(AVehicle veh, int groupId) { if (veh.HasGroup(groupId)) { return; } veh.AddGroup(groupId); if (veh.IsMy) { while (_myVehiclesByGroup.Count < groupId) { _myVehiclesByGroup.Add(new List <AVehicle>()); } _myVehiclesByGroup[groupId - 1].Add(veh); } }
private void _copyFrom(AVehicle unit) { IsMy = unit.IsMy; Type = unit.Type; Durability = unit.Durability; IsSelected = unit.IsSelected; RemainingAttackCooldownTicks = unit.RemainingAttackCooldownTicks; Groups = unit.Groups; CanChargeFacility = unit.CanChargeFacility; Action = unit.Action; MoveVectorOrRotationCenter = unit.MoveVectorOrRotationCenter; MoveSpeedOrAngularSpeed = unit.MoveSpeedOrAngularSpeed; MoveLengthOrRotationAngle = unit.MoveLengthOrRotationAngle; DurabilityPool = unit.DurabilityPool; }
public bool DoMoveApprox(AVehicle[] vehicles, bool moveApprox) { var result = true; if (moveApprox) { Logger.CumulativeOperationStart("DoMoveA"); for (var i = 0; i < vehicles.Length; i++) { var veh = vehicles[i]; if (_prevStateCache[i] == null) { _prevStateCache[i] = new AVehicle(veh); } else { _prevStateCache[i].CopyFrom(veh); } if (!veh.Move()) { // откатываем изменения for (var j = 0; j < i; j++) { var prevX = vehicles[j].X; var prevY = vehicles[j].Y; vehicles[j].CopyFrom(_prevStateCache[j]); _updateVehicleCoordinates(vehicles[j], prevX, prevY); } result = false; break; } _updateVehicleCoordinates(veh, _prevStateCache[i].X, _prevStateCache[i].Y); } Logger.CumulativeOperationEnd("DoMoveA"); } else { Logger.CumulativeOperationStart("DoMove1"); _doMove1(vehicles); Logger.CumulativeOperationEnd("DoMove1"); } return(result); }
private void _updateVehicleCoordinates(AVehicle veh, double prevX, double prevY) { var unitTree = _trees[veh.IsMy ? 1 : 0, veh.IsAerial ? 1 : 0]; if (unitTree == null) { return; // Дерево ещё не создано. Когда будет создаваться - тогда и наполнится обновленными данными. } var moveX = veh.X; var moveY = veh.Y; if (!Geom.PointsEquals(prevX, prevY, moveX, moveY)) { veh.X = prevX; veh.Y = prevY; if (!unitTree.ChangeXY(veh, moveX, moveY)) { throw new Exception("Can't change unit coordinates, id=" + veh.Id); } } }
private double _nuclearGetDamage(AVehicle veh, Sandbox env, double lowerBound, List <AVehicle> targets, out ANuclear nuclearResult) { var vr = veh.ActualVisionRange * 0.9; var cen = Utility.Average(targets); cen = veh + (cen - veh).Normalized() * Math.Min(vr, veh.GetDistanceTo(cen)); var nuclear = new ANuclear(cen.X, cen.Y, true, veh.Id, G.TacticalNuclearStrikeDelay); nuclearResult = nuclear; var totalOpponentDamage = targets.Sum(x => x.GetNuclearDamage(nuclear)); if (totalOpponentDamage <= lowerBound) { return(totalOpponentDamage); } var totalDamage = totalOpponentDamage - env.GetMyNeighbours(nuclear.X, nuclear.Y, nuclear.Radius) .Sum(x => x.GetNuclearDamage(nuclear)); return(totalDamage); }
public AVehicle(AVehicle unit) : base(unit) { _copyFrom(unit); }
private void _doMove1(AVehicle[] vehicles) { var unblockedLength = 0; for (var i = 0; i < vehicles.Length; i++) { var veh = vehicles[i]; if (veh.Action == AVehicle.MoveType.None) { veh.Move(); _complete[i] = true; continue; } if (_movedState[i] == null) { _movedState[i] = new AVehicle(veh); } else { _movedState[i].CopyFrom(veh); } if (!_movedState[i].Move()) { veh.CopyFrom(_movedState[i]); _complete[i] = true; continue; } _unblocked[unblockedLength++] = i; _complete[i] = false; veh.Index = i; if (_deps[i] == null) { _deps[i] = new int[MagicMaxDependenciesCount]; } _depsLen[i] = 0; } while (unblockedLength > 0) { var unblockedNewLength = 0; for (var i = 0; i < unblockedLength; i++) { var idx = _unblocked[i]; var movedUnit = _movedState[idx]; var unitTree = _tree(movedUnit.IsMy, movedUnit.IsAerial); var oppTree = _tree(!movedUnit.IsMy, movedUnit.IsAerial); var intersectsWith = -1; do { { var nearest = unitTree.FindFirstNearby(movedUnit, Geom.Sqr(2 * movedUnit.Radius)); if (nearest != null) { if (nearest.IntersectsWith(movedUnit)) { intersectsWith = nearest.Index; break; } } } if (!movedUnit.IsAerial && CheckCollisionsWithOpponent) { var nearest = oppTree.FindFirstNearby(movedUnit, Geom.Sqr(2 * movedUnit.Radius)); if (nearest != null) { if (nearest.IntersectsWith(movedUnit)) { intersectsWith = nearest.Index; break; } } } } while (false); if (intersectsWith != -1) { if (!_complete[intersectsWith]) { _deps[intersectsWith][_depsLen[intersectsWith]++] = idx; } } else { var unit = vehicles[idx]; var prevX = unit.X; var prevY = unit.Y; unit.CopyFrom(movedUnit); if (!Geom.PointsEquals(prevX, prevY, movedUnit.X, movedUnit.Y)) { unit.X = prevX; unit.Y = prevY; if (!unitTree.ChangeXY(unit, movedUnit.X, movedUnit.Y)) { throw new Exception("Can't change unit coordinates, id=" + unit.Id); } if (_nearestFightersCacheTick != null && _nearestFightersCacheTick[idx] != -1) { _nearestFightersCacheDist[idx] -= unit.GetDistanceTo(prevX, prevY); } } } if (intersectsWith == -1 || _complete[intersectsWith]) { // resolve dependencies _complete[idx] = true; for (var k = 0; k < _depsLen[idx]; k++) { _unblocked2[unblockedNewLength++] = _deps[idx][k]; } } } unblockedLength = unblockedNewLength; Utility.Swap(ref _unblocked, ref _unblocked2); } }
public bool IsVisible(AVehicle vehicle) { var visionRange = vehicle.ActualVisionRange * vehicle.StealthFactor; return(visionRange * visionRange + Const.Eps >= GetDistanceTo2(vehicle)); }
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 static AVehicle _cloneVehicle(AVehicle vehicle) { return(new AVehicle(vehicle)); }
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)); }