void Initialize() { if (!Const.Initialized) { Const.Initialized = true; Const.TileSize = Const.Game.TrackTileSize; Const.TileMargin = Const.Game.TrackTileMargin; Const.CarDiagonalHalfLength = Geom.Gypot(Const.Game.CarWidth, Const.Game.CarHeight) / 2; Const.BonusDiagonalHalfLength = Geom.Gypot(Const.Game.BonusSize / 2 - MagicConst.BonusSafeMargin, Const.Game.BonusSize / 2 - MagicConst.BonusSafeMargin); Const.MapWidth = Const.TileSize * world.Width; Const.MapHeight = Const.TileSize * world.Height; } Teammate = world.Cars.FirstOrDefault(car => car.IsTeammate && car.Id != self.Id); ComputedPath.Remove(self.Id); if (Teammate != null) TeammateCar = ComputedPath.ContainsKey(Teammate.Id) ? ComputedPath[Teammate.Id] : null; if (Players == null) // check for first call { MyTiles = new ATile[world.Height, world.Width]; for (var i = 0; i < world.Height; i++) for (var j = 0; j < world.Width; j++) MyTiles[i, j] = new ATile(i, j, TileType.Unknown); } // intialize tiles var t = world.TilesXY; for (var i = 0; i < world.Height; i++) { for (var j = 0; j < world.Width; j++) { if (MyTiles[i, j].Type == TileType.Unknown && t[j][i] != TileType.Unknown) MyTiles[i, j] = new ATile(i, j, t[j][i]); MyTiles[i, j].Weight = 0; } } // intialize waypoints var wp = world.Waypoints; Waypoints = new Cell[wp.Length]; for(var i = 0; i < Waypoints.Length; i++) Waypoints[i] = new Cell(wp[i][1], wp[i][0]); Players = new Dictionary<long, Player>(); foreach (var player in world.Players) Players[player.Id] = player; foreach (var car in world.Cars) { DurabilityObserver.Watch(car); } var tires = world.Projectiles.Where(x => x.Type == ProjectileType.Tire).ToArray(); Tires = new AProjectile[tires.Length][]; #if DEBUG var trajectories = Tires.Select(x => new Points()).ToArray(); #endif for (var i = 0; i < tires.Length; i++) { Tires[i] = new AProjectile[MagicConst.ProjectilePredictionTicks]; Tires[i][0] = new AProjectile(tires[i]); for (var j = 1; j < MagicConst.ProjectilePredictionTicks; j++) { Tires[i][j] = Tires[i][j - 1].Clone(); Tires[i][j].Move(); #if DEBUG trajectories[i].Add(new Point(Tires[i][j])); #endif } } #if DEBUG foreach (var tr in trajectories) Visualizer.SegmentsDrawQueue.Add(new object[] {Brushes.Indigo, tr, 0.0}); #endif Bonuses = world.Bonuses.Select(b => new ABonus(b)).ToArray(); OilSlicks = world.OilSlicks.Select(s => new AOilSlick(s)).ToArray(); EnumerateNeigbours(GetCell(self), to => { var center = GetCenter(to); MyTiles[to.I, to.J].Weight += Math.Abs(self.GetAngleTo(center.X, center.Y)); }); foreach (var bonus in Bonuses) { var cell = GetCell(bonus); MyTiles[cell.I, cell.J].AddBonus(bonus); } foreach (var slick in OilSlicks) { var cell = GetCell(slick); MyTiles[cell.I, cell.J].AddSlick(slick); } Opponents = world.Cars.Where(car => !car.IsTeammate && !car.IsFinishedTrack).ToArray(); PrepareOpponentsPath(); if (OpponentsCars != null) Others = OpponentsCars .Concat(TeammateCar == null ? new ACar[][] { } : new[] { TeammateCar }) .ToArray(); ComputedPath.Clear(); if (self.TeammateIndex == 1 && OpponentsCars != null) { foreach (var opp in OpponentsCars) ComputedPath[opp[0].Original.Id] = opp; } }
public bool CheckUseProjectile() { if (world.Tick < Const.Game.InitialFreezeDurationTicks) { return(false); } if (self.ProjectileCount == 0) { return(false); } if (self.RemainingProjectileCooldownTicks > 0) { return(false); } var projectiles = AProjectile.GetProjectiles(new ACar(self)); var shot = new bool[projectiles.Length]; var shotSpeed = 0.0; var checkTicks = MagicConst.OpponentsTicksPrediction * (self.Type == CarType.Buggy ? 0.5 : 0.4); for (var t = 1; t < checkTicks; t++) { for (var prId = 0; prId < projectiles.Length; prId++) { var pr = projectiles[prId]; if (!pr.Exists) { continue; } pr.Move(); for (var i = 0; i < All.Length; i++) { if (t >= All[i].Length) { continue; } var car = All[i][t]; /* * Чужие машинки считать меньшими по размеру * Свои - большими */ if (pr.Intersect(car, car.Original.IsTeammate ? 5 : -(pr.Type == ProjectileType.Tire ? 40 : 5))) { if (pr.Type == ProjectileType.Tire) { // если это я только что выпустил шину if (car.Original.Id == self.Id && Math.Abs(pr.Speed.Length - Const.Game.TireInitialSpeed) < Eps) { continue; } } else { // если это я выпустил шайбу if (car.Original.Id == self.Id) { continue; } } if (car.Original.IsTeammate) // попал в своего { return(false); } if (DurabilityObserver.ReactivationTime(car.Original) + 2 < world.Tick + t || DurabilityObserver.IsActive(car.Original)) { // если он не мертв shot[prId] = true; if (pr.Type == ProjectileType.Tire) { shotSpeed = pr.Speed.Length; } } pr.Exists = false; } } } } var shotCount = shot.Count(val => val); if (self.Type == CarType.Buggy) { return(shotCount >= 3 || shotCount == 2 && self.ProjectileCount > 2); } return(shotCount == 1 && (shotSpeed >= Const.Game.TireInitialSpeed - Eps || shotSpeed >= Const.Game.TireInitialSpeed / 2.5 && self.ProjectileCount > 2)); }
void Initialize() { if (!Const.Initialized) { Const.Initialized = true; Const.TileSize = Const.Game.TrackTileSize; Const.TileMargin = Const.Game.TrackTileMargin; Const.CarDiagonalHalfLength = Geom.Gypot(Const.Game.CarWidth, Const.Game.CarHeight) / 2; Const.BonusDiagonalHalfLength = Geom.Gypot(Const.Game.BonusSize / 2 - MagicConst.BonusSafeMargin, Const.Game.BonusSize / 2 - MagicConst.BonusSafeMargin); Const.MapWidth = Const.TileSize * world.Width; Const.MapHeight = Const.TileSize * world.Height; } Teammate = world.Cars.FirstOrDefault(car => car.IsTeammate && car.Id != self.Id); ComputedPath.Remove(self.Id); if (Teammate != null) { TeammateCar = ComputedPath.ContainsKey(Teammate.Id) ? ComputedPath[Teammate.Id] : null; } if (Players == null) // check for first call { MyTiles = new ATile[world.Height, world.Width]; for (var i = 0; i < world.Height; i++) { for (var j = 0; j < world.Width; j++) { MyTiles[i, j] = new ATile(i, j, TileType.Unknown); } } } // intialize tiles var t = world.TilesXY; for (var i = 0; i < world.Height; i++) { for (var j = 0; j < world.Width; j++) { if (MyTiles[i, j].Type == TileType.Unknown && t[j][i] != TileType.Unknown) { MyTiles[i, j] = new ATile(i, j, t[j][i]); } MyTiles[i, j].Weight = 0; } } // intialize waypoints var wp = world.Waypoints; Waypoints = new Cell[wp.Length]; for (var i = 0; i < Waypoints.Length; i++) { Waypoints[i] = new Cell(wp[i][1], wp[i][0]); } Players = new Dictionary <long, Player>(); foreach (var player in world.Players) { Players[player.Id] = player; } foreach (var car in world.Cars) { DurabilityObserver.Watch(car); } var tires = world.Projectiles.Where(x => x.Type == ProjectileType.Tire).ToArray(); Tires = new AProjectile[tires.Length][]; #if DEBUG var trajectories = Tires.Select(x => new Points()).ToArray(); #endif for (var i = 0; i < tires.Length; i++) { Tires[i] = new AProjectile[MagicConst.ProjectilePredictionTicks]; Tires[i][0] = new AProjectile(tires[i]); for (var j = 1; j < MagicConst.ProjectilePredictionTicks; j++) { Tires[i][j] = Tires[i][j - 1].Clone(); Tires[i][j].Move(); #if DEBUG trajectories[i].Add(new Point(Tires[i][j])); #endif } } #if DEBUG foreach (var tr in trajectories) { Visualizer.SegmentsDrawQueue.Add(new object[] { Brushes.Indigo, tr, 0.0 }); } #endif Bonuses = world.Bonuses.Select(b => new ABonus(b)).ToArray(); OilSlicks = world.OilSlicks.Select(s => new AOilSlick(s)).ToArray(); EnumerateNeigbours(GetCell(self), to => { var center = GetCenter(to); MyTiles[to.I, to.J].Weight += Math.Abs(self.GetAngleTo(center.X, center.Y)); }); foreach (var bonus in Bonuses) { var cell = GetCell(bonus); MyTiles[cell.I, cell.J].AddBonus(bonus); } foreach (var slick in OilSlicks) { var cell = GetCell(slick); MyTiles[cell.I, cell.J].AddSlick(slick); } Opponents = world.Cars.Where(car => !car.IsTeammate && !car.IsFinishedTrack).ToArray(); PrepareOpponentsPath(); if (OpponentsCars != null) { Others = OpponentsCars .Concat(TeammateCar == null ? new ACar[][] { } : new[] { TeammateCar }) .ToArray(); } ComputedPath.Clear(); if (self.TeammateIndex == 1 && OpponentsCars != null) { foreach (var opp in OpponentsCars) { ComputedPath[opp[0].Original.Id] = opp; } } }