private double AngelToWayPoint(Car self, World world, Game game, Move move) { double nextWaypointX = (self.NextWaypointX + 0.5D) * game.TrackTileSize; double nextWaypointY = (self.NextWaypointY + 0.5D) * game.TrackTileSize; double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY); double max = .32D; double delta = speedModule / MaxSpeed; double cornerTileOffset = max * delta * game.TrackTileSize; switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY]) { case TileType.LeftTopCorner: nextWaypointX += cornerTileOffset; nextWaypointY += cornerTileOffset; break; case TileType.RightTopCorner: nextWaypointX -= cornerTileOffset; nextWaypointY += cornerTileOffset; break; case TileType.LeftBottomCorner: nextWaypointX += cornerTileOffset; nextWaypointY -= cornerTileOffset; break; case TileType.RightBottomCorner: nextWaypointX -= cornerTileOffset; nextWaypointY -= cornerTileOffset; break; } return self.GetAngleTo(nextWaypointX, nextWaypointY); }
public SimulatedPosition(Car self, Game game) { this.game = game; position = new Vector(self.X,self.Y); speed = new Vector(self.SpeedX,self.SpeedY); enginePower = self.EnginePower; }
public void Move(Car self, World world, Game game, Move move) { move.EnginePower = 1.0D; move.IsThrowProjectile = true; move.IsSpillOil = true; if (world.Tick > game.InitialFreezeDurationTicks) { move.IsUseNitro = true; } }
public void Move(Car self, World world, Game game, Move move) { double nextWaypointX = (self.NextWaypointX + 0.5) * game.TrackTileSize; double nextWaypointY = (self.NextWaypointY + 0.5) * game.TrackTileSize; Console.WriteLine (self.NextWaypointX + " " + self.NextWaypointY); double cornerTileOffset = 0.25D * game.TrackTileSize; switch (world.TilesXY [self.NextWaypointX] [self.NextWaypointY]) { case TileType.LeftTopCorner: nextWaypointX += cornerTileOffset; nextWaypointY += cornerTileOffset; break; case TileType.RightTopCorner: nextWaypointX -= cornerTileOffset; nextWaypointY += cornerTileOffset; break; case TileType.LeftBottomCorner: nextWaypointX += cornerTileOffset; nextWaypointY -= cornerTileOffset; break; case TileType.RightBottomCorner: nextWaypointX -= cornerTileOffset; nextWaypointY -= cornerTileOffset; break; } double angleToWaypoint = self.GetAngleTo (nextWaypointX, nextWaypointY); double speedModule = hypot (self.SpeedX, self.SpeedY); move.WheelTurn = (angleToWaypoint * 32.0D / System.Math.PI); move.EnginePower = (1.0D); if (speedModule > 30) move.EnginePower = 0; if (speedModule * speedModule * System.Math.Abs (angleToWaypoint) > 2.5D * 2.5D * System.Math.PI) { move.EnginePower = (0.0D); if (speedModule > 10) { move.IsBrake = true; if (angleToWaypoint > 0) move.WheelTurn = 1; else move.WheelTurn = -1; } } move.IsThrowProjectile = true; move.IsSpillOil = true; }
public void Move(Car self, World world, Game game, Move move) { double nextWaypointX = (self.NextWaypointX + 0.5D) * game.TrackTileSize; double nextWaypointY = (self.NextWaypointY + 0.5D) * game.TrackTileSize; double angleToWaypoint = self.GetAngleTo(nextWaypointX, nextWaypointY); if (backNumber < maxBackNumber) { backNumber++; move.WheelTurn = -oldAngle; move.EnginePower = -1; number = -100; return; } double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY); if (Math.Abs(speedModule) < .05) number++; else number = 0; if (number > maxNumber) { backNumber = 0; number = 0; oldAngle = angleToWaypoint * 32.0D / Math.PI; } move.EnginePower = 1; if (Math.Abs(nextWaypointX - self.X) < 1600 && Math.Abs(nextWaypointY - self.Y) < 1600) { angleToWaypoint = AngelToWayPoint(self, world, game, move); move.IsBrake = IsUseBreak(self, world, game, move); } move.WheelTurn = angleToWaypoint * 32.0D / Math.PI; Console.WriteLine(String.Format("{0} - {1}", self.SpeedX, self.SpeedY)); move.IsUseNitro = IsUseNitro(self, world, game, move); move.IsThrowProjectile = IsThrow(self, world, game, move); move.IsSpillOil = IsSpillOil(self, world, game, move); veryOldTileType = oldTileType; oldTileType = world.TilesXY[self.NextWaypointX][self.NextWaypointY]; Console.WriteLine(speedModule); }
public void Move(Car self, World world, Game game, Move move) { Debug.beginPost(); Constants.setConstants(game, world); currentTick = world.Tick; if (map == null) { waypoints = world.Waypoints; map = new RoadMap(world.Width, world.Height); map.updateMap(world.TilesXY); } if (currentVehicle == null) { currentVehicle = new ManagedVehicle(); } currentVehicle.setCar(self); currentVehicle.tick(move); Debug.endPost(); }
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) { TimerStart(); MyStrategy.world = world; Const.Game = game; this.move = move; this.self = self; Initialize(); #if DEBUG while (Visualizer.Pause) { // pause here } Visualizer.CreateForm(world.Cars.Count(x => x.IsTeammate)); #endif if (!self.IsFinishedTrack) { All = null; MyTeam = null; _move(); if (OpponentsCars != null) { var myTeam = new List<ACar[]>(); if (!ComputedPath.ContainsKey(self.Id)) ComputedPath[self.Id] = new int[MagicConst.OpponentsTicksPrediction].Select(x => new ACar(self)).ToArray(); myTeam.Add(ComputedPath[self.Id]); if (TeammateCar != null) myTeam.Add(TeammateCar); MyTeam = myTeam.ToArray(); All = MyTeam.Concat(OpponentsCars).ToArray(); TimerStart(); if (CheckUseProjectile()) move.IsThrowProjectile = true; if (CheckUseOil()) move.IsSpillOil = true; TimerEndLog("CheckUseProjectile", 2); } } else if (_finishTime == Infinity) _finishTime = world.Tick; if (_finishTime < Infinity) Log(_finishTime); #if DEBUG if (move.IsBrake) Visualizer.CircleFillQueue.Add(new Tuple<Brush, ACircularUnit>(Brushes.Red, new ACircularUnit {X = self.X, Y = self.Y, Radius = 30})); TimerEndLog("All"); if (Brutes != null) { for (var i = 0; i < Brutes.Length; i++) { var info = Brutes[i].GetMaxTicksInfo(); if (info == null) continue; Console.Write(i + ": "); foreach (var a in info) Console.Write(" " + a); Console.WriteLine("(" + Brutes[i].SelectedCount + ")"); } } Console.WriteLine(); Visualizer.Draw(); Thread.Sleep(12); #endif }
private bool IsUseNitro(Car self, World world, Game game, Move move) { int currentTileX = (int)(self.X / game.TrackTileSize); int currentTileY = (int)(self.Y / game.TrackTileSize); switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY]) { case TileType.LeftBottomCorner: case TileType.LeftTopCorner: case TileType.RightBottomCorner: case TileType.RightTopCorner: return false; } switch (world.TilesXY[currentTileX][currentTileY]) { case TileType.Crossroads: case TileType.Horizontal: case TileType.Vertical: return true; default: return false; } }
private bool IsUseBreak(Car self, World world, Game game, Move move) { double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY); switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY]) { case TileType.LeftBottomCorner: case TileType.LeftTopCorner: case TileType.RightBottomCorner: case TileType.RightTopCorner: if (speedModule > MaxSpeed) { move.EnginePower = .8d; return true; } break; default: return false; } return false; }
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; }
private bool IsSpillOil(Car self, World world, Game game, Move move) { int currentTileX = (int)(self.X / game.TrackTileSize); int currentTileY = (int)(self.Y / game.TrackTileSize); switch (world.TilesXY[currentTileX][currentTileY]) { case TileType.LeftBottomCorner: case TileType.LeftTopCorner: case TileType.RightBottomCorner: case TileType.RightTopCorner: return true; default: return false; } }
public static void setConstants(Game _game, World _world) { game = _game; world = _world; }
public void Move(Car self, World world, Game game, Move move) { lastX1 = lastX2; lastX2 = lastX3; lastX3 = Math.Round(self.X, 2); lastY1 = lastY2; lastY2 = lastY3; lastY3 = Math.Round(self.Y, 2); this._game = game; this._move = move; this._self = self; this._world = world; if (rearMove) { move.EnginePower = -1.0D; move.WheelTurn = 0;//(activeTicks > 50) ? -1 : 0; } if (activeTicks == 90 && Math.Abs (lastX1 - lastX3) < 0.05 && Math.Abs (lastY1 - lastY3) < 0.05 && _world.Tick > _game.InitialFreezeDurationTicks) rearMove = false; if (activeTicks > 0) { activeTicks --; return; } if (noStuck > 0) noStuck--; if (slowDown > 0) { move.EnginePower = 0.5D; } else move.EnginePower = 1.0D; if (noIgnite > 0) { noIgnite--; //return; } move.IsThrowProjectile = false; move.IsSpillOil = false; if (world.Tick > game.InitialFreezeDurationTicks && world.Tick < game.InitialFreezeDurationTicks + 10) { move.WheelTurn = -15; } if (world.Tick > game.InitialFreezeDurationTicks && world.Tick < game.InitialFreezeDurationTicks + 20) { // move.IsSpillOil = true; // move.WheelTurn = 0; sDirection = world.StartingDirection; } if (world.Tick > game.InitialFreezeDurationTicks && world.Tick < game.InitialFreezeDurationTicks + 10 && move.WheelTurn == 0) { // move.WheelTurn = 1; } if (world.Tick > game.InitialFreezeDurationTicks + 30) { move.IsUseNitro = (noIgnite == 0); CheckTurn(); NewTurnWheel (); CheckStuck (); if (Math.Abs(_move.WheelTurn) > Math.PI / 6) move.IsUseNitro = false; } if (_thisTile != TileType.Empty) { // saveDirection = sDirection; } }
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; }
public SimulatedPosition Simulate(int ticks, int step, Car self, World world, Game game, SimulatedControl control) { SimulatedPosition pos = new SimulatedPosition(self, game); this.game = game; for (int t = 0; t < ticks; t += step) { for (int a = 0; a < 10; a++) { //pos.enginePower = AgjustPower(pos.enginePower, control.enginePower, 0.1); pos.Update(0.1); } } return pos; }