private bool IsThrow(Car self, World world, Game game, Move move) { int maxShootDistance = 1000; if (self.ProjectileCount <= 0) { return false; } foreach (Car c in world.Cars) { if (c.IsTeammate) { continue; } double enemyCarAngel = self.GetAngleTo(c.X, c.Y); Console.WriteLine(self.GetDistanceTo(c)); if (self.GetDistanceTo(c) > maxShootDistance) { continue; } if (Math.Abs(enemyCarAngel) < 0.1) { return true; } } return false; }
public void Move(Car self, World world, Game game, Move move) { if (stop) return; if (world.Tick == 0) { startX = self.X; startY = self.Y; prevX = self.X; prevY = self.Y; } move.EnginePower = 0; if (world.Tick > game.InitialFreezeDurationTicks) { double nextWaypointX = (self.NextWaypointX + 0.5D) * game.TrackTileSize; double nextWaypointY = (self.NextWaypointY + 0.5D) * game.TrackTileSize; double angleToWaypoint = self.GetAngleTo(nextWaypointX, nextWaypointY); double distToWaypoint = self.GetDistanceTo(nextWaypointX, nextWaypointY); double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY); travelled += self.GetDistanceTo(prevX, prevY); travelled2 += self.GetDistanceTo(prevX, prevY); prevX = self.X; prevY = self.Y; move.EnginePower = 1; if (travelled > 1500) { move.EnginePower = 0; if (self.EnginePower == 0) { if (t == -10) { travelled2 = 0; Console.WriteLine("S: {0},{1} {2}", self.X, self.Y, self.SpeedY); t = 1; SimulatedControl ctrl = new SimulatedControl(); ctrl.enginePower = move.EnginePower; pos = simulator.Simulate(t, 1, self, world, game, ctrl); Console.WriteLine("P: {0},{1} {2}", pos.position.X, pos.position.Y, pos.speed.Y); } else if (t > 1) { t--; } else if (t == 1) { t--; Console.WriteLine("R: {0},{1} {2}", self.X, self.Y, self.SpeedY); Console.WriteLine("%: {0} / {1} ({2})", travelled2, self.GetDistanceTo(pos.position.X, pos.position.Y), 100 * self.GetDistanceTo(pos.position.X, pos.position.Y) / travelled2); } } } } }
public void Move(Car self, World world, Game game, Move move) { if (world.Tick == 0) { // Инициализация TilesXY = new TileType[world.TilesXY.Length][]; for (int t = world.TilesXY.Length - 1; t >= 0; --t) { TilesXY[t] = new TileType[world.TilesXY[t].Length]; Array.Copy(world.TilesXY[t], TilesXY[t], world.TilesXY[t].Length); } } // Предстартовое повышение мощности двигателя на холостых оборотах if (world.Tick <= game.InitialFreezeDurationTicks) { move.EnginePower = 1.0D; return; } // Координаты машины в таблице тайлов int x = (int)(self.X / game.TrackTileSize); int y = (int)(self.Y / game.TrackTileSize); // Перерасчет пути if (X != x || Y != y) { X = x; Y = y; int[][] LocalPathX = new int[3][]; int[][] LocalPathY = new int[3][]; // Путь между машиной и ближайшей путевой точкой FindTargets( X, Y, world.Waypoints[self.NextWaypointIndex][0], world.Waypoints[self.NextWaypointIndex][1], out LocalPathX[0], out LocalPathY[0]); // Путь между очередной путевой точкой и следующей путевой точкой for (int i = 0; i < LocalPathX.Length - 1; ++i) FindTargets( world.Waypoints[(self.NextWaypointIndex + i) % world.Waypoints.Length][0], world.Waypoints[(self.NextWaypointIndex + i) % world.Waypoints.Length][1], world.Waypoints[(self.NextWaypointIndex + i + 1) % world.Waypoints.Length][0], world.Waypoints[(self.NextWaypointIndex + i + 1) % world.Waypoints.Length][1], out LocalPathX[i + 1], out LocalPathY[i + 1]); // Путь от машины через промежуточные путевые точки к следующей путевой точке int Len = 0; for (int i = 0; i <= LocalPathX.Length - 1; ++i) Len += LocalPathX[i].Length; PathX = new int[Len]; PathY = new int[Len]; Len = 0; for (int i = 0; i <= LocalPathX.Length - 1; ++i) { for (int j = LocalPathX[i].Length - 1; j >= 0; --j) { PathX[Len + j] = LocalPathX[i][j]; PathY[Len + j] = LocalPathY[i][j]; } Len += LocalPathX[i].Length; } // Срезание углов на поворотах correctX = 0.5; correctY = 0.5; // Определение длины прямолинейного участка пути n = 0; if (PathX[n] == X) { int dY = PathY[n] - Y; // Отрезок по вертикали while (PathX[n] == X && n < PathX.Length - 1) if (PathX[n + 1] == X && dY == PathY[n + 1] - PathY[n]) n++; else break; // Срезание углов на поворотах if (n < PathX.Length - 1) { if (PathX[n + 1] < PathX[n]) correctX = 0.2; else correctX = 0.8; } } else if (PathY[n] == Y) { int dX = PathX[n] - X; // Отрезок по горизонтали while (PathY[n] == Y && n < PathY.Length - 1) if (PathY[n + 1] == Y && dX == PathX[n + 1] - PathX[n]) n++; else break; // Срезание углов на поворотах if (n < PathX.Length - 1) { if (PathY[n + 1] < PathY[n]) correctY = 0.2; else correctY = 0.8; } } } // Прицельная точка - ближайший поворот double nextX = (PathX[n] + correctX) * game.TrackTileSize; double nextY = (PathY[n] + correctY) * game.TrackTileSize; // Расчет положения руля и педали газа - цель nextX, nextY double power, turn; GoTo(self, nextX, nextY, 0, 0, out power, out turn); move.EnginePower = power; move.WheelTurn = turn; // Подбор попутных бонусов bool bonus = false; foreach (Bonus b in world.Bonuses) { bool OnPath = false; for (int i = 0; i < n; i++) if ((int)(b.X / game.TrackTileSize) == PathX[i] && (int)(b.Y / game.TrackTileSize) == PathY[i]) OnPath = true; double angle = GetAngleBetween(self.X, self.Y, b.X, b.Y, self.Angle); angle += GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle); if (Math.Abs(angle) < Math.PI / 12.0 && self.GetDistanceTo(b) < (n - 1) * game.TrackTileSize && OnPath) { if (GetDistance(self, nextX, nextY) > GetDistance(self, b.X, b.Y)) { nextX = b.X; nextY = b.Y; GoTo(self, nextX, nextY, 0, 0, out power, out turn); move.EnginePower = power; move.WheelTurn = turn; bonus = true; } } } // Торможение при приближении к повороту if (!bonus) if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) * 33 > self.GetDistanceTo(nextX, nextY)) { if (Math.Abs(GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle)) < Math.PI / 2 && move.EnginePower > 0) move.IsBrake = true; if (Math.Abs(GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle)) > Math.PI / 2 && move.EnginePower < 0) move.IsBrake = true; move.EnginePower = -move.EnginePower; } // Взаимодействие с соперниками foreach (Car c in world.Cars) if (!c.IsTeammate) { if (Math.Abs(GetAngleBetween(self.X, self.Y, c.X, c.Y, self.Angle)) < Math.PI / 90.0 && self.GetDistanceTo(c) < 2400) move.IsThrowProjectile = true; if (Math.Abs(GetAngleBetween(self.X, self.Y, c.X, c.Y, Math.PI + self.Angle)) < Math.PI / 90.0 && self.GetDistanceTo(c) < 2400) if (Math.Abs(self.AngularSpeed) > 0.005) move.IsSpillOil = true; } // Если скорость меньше 1, то засекаем 60 тиков. // Если скорость не изменилась за это время, то 60 тиков выруливать из тупика // Засекаем 60 тиков перед включением режима выруливания if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) < 1 && TickStop == -1) TickStop = world.Tick; // Отмена режима выруливания, если скорость поднялась или вышло время работы режима if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) > 1 && (world.Tick - TickStop <= 60) || (TickStop != -1 && world.Tick - TickStop > 160) || GetDistance(self.SpeedX, self.SpeedY, 0, 0) > 10) TickStop = -1; // Режим выруливания 100 тиков if (TickStop != -1 && world.Tick - TickStop > 60 && world.Tick - TickStop <= 160) { GoTo(self, 2 * self.X - nextX, 2 * self.Y - nextY, 0, 0, out power, out turn); move.EnginePower = power; move.WheelTurn = turn; } if (TickStop != -1 && world.Tick - TickStop > 140 && world.Tick - TickStop <= 160) { GoTo(self, nextX, nextY, 0, 0, out power, out turn); move.EnginePower = power; } // Ускоряться if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) > 1 && GetDistance(self.SpeedX, self.SpeedY, 0, 0) < 20) if (n > 5 && Math.Abs(GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle)) < Math.PI / 8.0D) move.IsUseNitro = true; }