public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { if (tilePath.Count < 4) return false; var current = MyStrategy.map.tileAt(vehicle.position); var currentToFirst = current.directionForTile(tilePath[0]).Value; var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value; var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value; var thirdToFour = tilePath[2].directionForTile(tilePath[3]).Value; if (!currentToFirst.isSameAxis(firstToSecond)) return false; if (firstToSecond.isSameAxis(secondToThird)) return false; if (firstToSecond.back() != thirdToFour) return false; var turningFrom = new Vector(currentToFirst); var turningTo = new Vector(firstToSecond); move.EnginePower = 1; move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, current.center, turningTo, -0.25 * Constants.tileSize)); if (vehicle.speed.length > 15) { move.IsBrake = true; } else { move.IsBrake = false; } return true; }
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 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 override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { var nextTile = tilePath[0]; // nextTile.draw(0xFF0000); // nextTile.center.draw(0xFF1010); if (vehicle.forward * (nextTile.center - vehicle.position) < 0.4 && vehicle.speed.length > 10) { move.IsBrake = true; move.EnginePower = -1; } else { move.IsBrake = false; move.EnginePower = 1; } move.WheelTurn = vehicle.forward.angleTo((nextTile.center - vehicle.position)) * 4; return 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 run() { try { remoteProcessClient.WriteTokenMessage(token); int teamSize = remoteProcessClient.ReadTeamSizeMessage(); remoteProcessClient.WriteProtocolVersionMessage(); Game game = remoteProcessClient.ReadGameContextMessage(); IStrategy[] strategies = new IStrategy[teamSize]; for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) { strategies[strategyIndex] = new MyStrategy(); } PlayerContext playerContext; while ((playerContext = remoteProcessClient.ReadPlayerContextMessage()) != null) { Car[] playerCars = playerContext.Cars; if (playerCars == null || playerCars.Length != teamSize) { break; } Move[] moves = new Move[teamSize]; for (int carIndex = 0; carIndex < teamSize; ++carIndex) { Car playerCar = playerCars[carIndex]; Move move = new Move(); moves[carIndex] = move; strategies[playerCar.TeammateIndex].Move(playerCar, playerContext.World, game, move); } remoteProcessClient.WriteMovesMessage(moves); } } finally { remoteProcessClient.Close(); } }
public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { var current = MyStrategy.map.tileAt(vehicle.position); AxisDirection dir; { dir = current.directionForTile(tilePath[0]) ?? AxisDirection.up; for (int i = 1; i < 3 && i < tilePath.Count; ++i) { if (tilePath[i - 1].directionForTile(tilePath[i]) != dir) return false; } } var dirVec = new Vector(dir); var last = current; int lineTilesCtr = 0; foreach (var tile in tilePath) { if (dir.turnLeft() == last.directionForTile(tile)) { var turnVector = new Vector(dir.turnLeft()); var dist = (vehicle.position - current.center) * turnVector + 0.15 * Constants.tileSize; dirVec -= turnVector * dist / Constants.tileSize; break; } else if (dir.turnRight() == last.directionForTile(tile)) { var turnVector = new Vector(dir.turnRight()); var dist = (vehicle.position - current.center) * turnVector + 0.15 * Constants.tileSize; dirVec -= turnVector * dist / Constants.tileSize; break; } else if (dir != last.directionForTile(tile)) break; lineTilesCtr += 1; last = tile; } if (lineTilesCtr >= 8) { move.IsUseNitro = true; } if (vehicle.forward * dirVec > 0.3) { move.EnginePower = 1; move.WheelTurn = vehicle.steeringAngleForDirection(dirVec); } else { move.EnginePower = 0.2; move.WheelTurn = vehicle.steeringAngleForDirection(dirVec); } move.IsBrake = false; return true; }
public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { if (tilePath.Count < 3) return false; var currentTile = MyStrategy.map.tileAt(vehicle.position); Vector turningTo; Vector turningFrom; { var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value; turningTo = new Vector(firstToSecond); if (firstToSecond != tilePath[1].directionForTile(tilePath[2])) { return false; } var currentToFirst = currentTile.directionForTile(tilePath[0]).Value; if (currentToFirst.isSameAxis(firstToSecond)) { return false; } turningFrom = new Vector(currentToFirst); } if (vehicle.speed.length > 10) { var innerSide1 = Ray.line( currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5, currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) + turningFrom * Constants.tileSize * 0.5 ); //innerSide1.draw(0x00FF00); var innerCircle = new Circle(currentTile.center + (turningTo + turningFrom) * Constants.tileSize * 0.5, Constants.roadMargin); //innerCircle.draw(0x00FF00); var innerCircleExtended = new Circle(innerCircle.position, innerCircle.radius + 10); var backWall = new Ray(tilePath[0].center + turningFrom * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningTo * Constants.tileSize * 0.5, turningTo * Constants.tileSize * 2); //backWall.draw(0x00FF00); if (vehicle.forward * turningFrom > 0.45) { var vv = new VirtualVehicle(vehicle); var steering = Math.Sign(turningFrom.angleTo(turningTo)); for (int i = 0; i < 100; ++i) { vv.simulateTick(1.0, steering); if (vv.rect.isIntersect(innerSide1) || vv.rect.isIntersect(innerCircle)) { move.EnginePower = 1; move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, currentTile.center, turningTo, -0.15 * Constants.tileSize)); move.IsBrake = false; return true; } if (vv.rect.isIntersect(backWall)) { move.IsBrake = true; move.EnginePower = 1; move.WheelTurn = steering; return true; } if (tilePath[1].rect.contains(vv.position)) { // защита от слишком быстрого захода в поворот и ударения в заднюю стенку for (int j = 0; j < 50; ++j) { vv.simulateTick(1, steering); if (vv.rect.isIntersect(backWall)) { move.EnginePower = 1; move.WheelTurn = steering; move.IsBrake = true; return true; } //vv.position.draw(0x00FF00); //vv.rect.draw(0x0000FF); } move.EnginePower = 1; move.WheelTurn = steering; move.IsBrake = false; return true; } //vv.position.draw(0xFF0000); //vv.rect.draw(0x0000FF); } } else if (vehicle.forward * turningTo > 0.5) { var vv = new VirtualVehicle(vehicle); var steering = Math.Sign(turningFrom.angleTo(turningTo)); for (int i = 0; i < 100; ++i) { vv.simulateTick(1.0, 0); if (vv.rect.isIntersect(innerSide1) || vv.rect.isIntersect(innerCircleExtended)) { move.EnginePower = 1; move.WheelTurn = -steering; move.IsBrake = false; return true; } if (tilePath[1].rect.contains(vv.position)) { move.EnginePower = 1; move.WheelTurn = 0; move.IsBrake = false; return true; } //vv.position.draw(0xFF0000); //vv.rect.draw(0x0000FF); } } else { move.IsBrake = true; move.WheelTurn = 0; move.EnginePower = 1; return true; } } move.IsBrake = false; move.EnginePower = 1; var turn = turningTo + turningFrom; move.WheelTurn = vehicle.steeringAngleForDirection(turn); return true; }
public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { var forceGetBack = false; if (MyStrategy.currentTick > 180) { if (vehicle.speed.length < 1) { zeroSpeedTicks += 1; } else { zeroSpeedTicks = 0; } if (zeroSpeedTicks > 30) { forceGetBack = true; } } if (vehicle.speed.length > 5 && !forceGetBack) return false; var target = tilePath[0].center; if (MyStrategy.map.intersect(vehicle.forwardRay * Constants.vehicleLength * 2) != null || forceGetBack) { move.IsBrake = false; move.EnginePower = -1; move.WheelTurn = -vehicle.forward.angleTo(target - vehicle.position) * 4; return true; } return false; }
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; } }
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 abstract bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move);
public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { if (tilePath.Count < 2) return false; var current = MyStrategy.map.tileAt(vehicle.position); var currentToFirst = current.directionForTile(tilePath[0]).Value; var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value; var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value; if (currentToFirst.isSameAxis(firstToSecond)) return false; if (currentToFirst.back() != secondToThird) return false; var turningFrom = new Vector(currentToFirst); var turningTo = new Vector(firstToSecond); if (vehicle.speed.length > 10) { var steering = Math.Sign(turningFrom.angleTo(turningTo)); var backWall = new Ray( tilePath[0].center + turningFrom * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningTo * Constants.tileSize * 0.5, turningTo * Constants.tileSize * 2 ); var backSideWall = new Ray( backWall.p2 - turningTo * Constants.roadMargin, -turningFrom * (Constants.tileSize - Constants.roadMargin) ); var innerWall = new Ray(current.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5, turningFrom * Constants.tileSize); var innerCircle = new Circle(current.center + (new Vector(currentToFirst) + new Vector(firstToSecond)) * Constants.tileSize * 0.5, Constants.roadMargin); backWall.draw(0x00FF00); backSideWall.draw(0x00FF00); innerWall.draw(0x00FF00); innerCircle.draw(0x00FF00); var vv = new VirtualVehicle(vehicle); for (int i = 0; i < 100; ++i) { vv.simulateTick(0.5, steering); var rect = vv.rect; if (rect.isIntersect(innerWall) || rect.isIntersect(innerCircle)) { move.EnginePower = 1; move.WheelTurn = -steering; move.IsBrake = false; return true; } if (rect.isIntersect(backWall) || rect.isIntersect(backSideWall)) { move.IsBrake = false; move.EnginePower = -1; //move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, current.center, turningTo, -0.25 * Constants.tileSize)); move.WheelTurn = steering; return true; } vv.position.draw(0xFF0000); vv.rect.draw(0x0000FF); } } move.EnginePower = 0.5; move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, current.center, turningTo, -0.25 * Constants.tileSize)); move.IsBrake = false; return true; }
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 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 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; } }
public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { if (tilePath.Count < 3) return false; var currentTile = MyStrategy.map.tileAt(vehicle.position); Vector target; Vector turningFrom; Vector turningTo; { var currentToFirst = currentTile.directionForTile(tilePath[0]).Value; var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value; var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value; if (currentToFirst != secondToThird) { return false; } if (firstToSecond.isSameAxis(currentToFirst)) { return false; } turningFrom = new Vector(currentToFirst); turningTo = new Vector(firstToSecond); target = tilePath[2].center - turningFrom * 0.5 * Constants.tileSize; } var vehicleToTarget = target - vehicle.position; if (vehicle.speed.length > 10 && vehicle.forward * (turningFrom + turningTo) > 0) { var steering = Math.Sign(turningFrom.angleTo(turningTo)); Ray side = new Ray( tilePath[0].center - turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5, turningFrom * (Constants.tileSize - Constants.roadMargin) ); Ray back = new Ray(side.p2, turningTo * (Constants.tileSize - Constants.roadMargin)); Circle backCircle = new Circle(back.p2 + turningFrom * Constants.roadMargin, Constants.roadMargin); Ray innerSide = new Ray( currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5, turningFrom * Constants.tileSize ); Circle innerCircle = new Circle(innerSide.p2 + turningTo * Constants.roadMargin, Constants.roadMargin); side.draw(0x00FF00); back.draw(0x00FF00); backCircle.draw(0x00FF00); innerSide.draw(0x00FF00); innerCircle.draw(0x00FF00); var vv = new VirtualVehicle(vehicle); for (int i = 0; i < 100; ++i) { vv.simulateTick(1.0, 0.0); var rect = vv.rect; if (rect.isIntersect(side) || rect.isIntersect(back) || rect.isIntersect(backCircle)) { vv = new VirtualVehicle(vehicle); for (int j = 0; j < 100; ++j) { vv.simulateTick(1, steering); if (rect.isIntersect(innerSide) || rect.isIntersect(innerCircle)) { move.EnginePower = 1; move.IsBrake = true; move.WheelTurn = steering; return true; } } move.EnginePower = 1; move.IsBrake = false; move.WheelTurn = steering; return true; } else if (rect.isIntersect(innerSide) || rect.isIntersect(innerCircle)) { vv = new VirtualVehicle(vehicle); for (int j = 0; j < 100; ++j) { vv.simulateTick(1, -steering); if (rect.isIntersect(innerSide) || rect.isIntersect(innerCircle)) { move.EnginePower = 1; move.IsBrake = true; move.WheelTurn = -steering; return true; } } move.EnginePower = 1; move.IsBrake = false; move.WheelTurn = -steering; return true; } if (tilePath[2].rect.contains(vv.position)) { move.EnginePower = 1; move.IsBrake = false; move.WheelTurn = vehicle.steeringAngleForDirection(vehicleToTarget); return true; } rect.draw(0x0000FF); vv.position.draw(0xFF0000); } move.EnginePower = 1; move.IsBrake = false; move.WheelTurn = vehicle.steeringAngleForDirection(vehicleToTarget); //new Ray(vehicle.position, vehicleToTarget).draw(0x00FFFF); return true; } if (vehicle.forward * vehicleToTarget < 0.5) { if (vehicle.speed.length > 10) { move.IsBrake = true; } move.EnginePower = 0.3; } else { move.EnginePower = 1; } move.WheelTurn = vehicle.steeringAngleForDirection(vehicleToTarget); move.IsBrake = false; return true; }
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 }
public void drive(Vehicle vehicle, List<Tile> tilePath, Move move) { //defaults move.IsUseNitro = false; foreach (var strategy in strategies) { if (strategy.tryDrive(vehicle, tilePath, move)) { Debug.print(vehicle.position + new Vector(15, 15), strategy.GetType().Name); return; } } //throw new Exception("Do not have strategy for this situation"); }
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 override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move) { if (tilePath.Count < 3) return false; var currentTile = MyStrategy.map.tileAt(vehicle.position); Vector turningTo; Vector turningFrom; { var currentToFirst = currentTile.directionForTile(tilePath[0]).Value; var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value; var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value; if (currentToFirst != firstToSecond) return false; if (firstToSecond.isSameAxis(secondToThird)) return false; if (tilePath.Count >= 4) { if (tilePath[2].directionForTile(tilePath[3]).Value.back() == currentToFirst) return false; } turningFrom = new Vector(currentToFirst); turningTo = new Vector(secondToThird); } if (vehicle.speed.length > 10 && vehicle.forward * turningFrom > 0.45) { var vv = new VirtualVehicle(vehicle); var steering = Math.Sign(turningFrom.angleTo(turningTo)); var innerSide1 = Ray.line( currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5, currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) + turningFrom * Constants.tileSize * 0.5 ); //innerSide1.draw(0x00FF00); var innerSide2 = new Ray(innerSide1.position + turningFrom * Constants.tileSize, innerSide1.direction); //innerSide2.draw(0x00FF00); var innerCircle = new Circle(currentTile.center + (turningTo + turningFrom) * Constants.tileSize * 0.5 + turningFrom * Constants.tileSize, Constants.roadMargin); //innerCircle.draw(0x00FF00); var backWall = new Ray(tilePath[1].center + turningFrom * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningTo * (Constants.tileSize * 0.5), turningTo * 2 * Constants.tileSize); //backWall.draw(0x00FF00); var outerSide = new Ray(currentTile.center - turningTo * (Constants.halfTileSize - Constants.roadMargin) - turningFrom * Constants.halfTileSize, turningFrom * Constants.tileSize * 3); //outerSide.draw(0x00FF00); for (int i = 0; i < 100; ++i) { vv.simulateTick(1.0, steering); if (vv.rect.isIntersect(innerSide1) || vv.rect.isIntersect(innerSide2)) break; if (vv.rect.isIntersect(innerCircle)) break; if (vv.rect.isIntersect(outerSide)) { var target = currentTile.center + turningFrom * Constants.tileSize * 1.5; move.WheelTurn = steering; move.EnginePower = 1; move.IsBrake = true; return true; } if (vv.rect.isIntersect(backWall)) { move.EnginePower = 1; move.WheelTurn = steering; move.IsBrake = true; return true; } if (tilePath[2].rect.contains(vv.position)) { // защита от слишком быстрого захода в поворот и ударения в заднюю стенку for (int j = 0; j < 50; ++j) { vv.simulateTick(1, steering); if (vv.rect.isIntersect(backWall)) { move.EnginePower = 1; move.WheelTurn = steering; move.IsBrake = true; return true; } //vv.position.draw(0x00FF00); //vv.rect.draw(0x0000FF); } move.EnginePower = 1; move.WheelTurn = steering; move.IsBrake = false; return true; } //vv.position.draw(0xFF0000); //vv.rect.draw(0x0000FF); } } move.WheelTurn = vehicle.steeringAngleForDirection((currentTile.center + turningFrom * Constants.tileSize * 1.5) - vehicle.position); move.EnginePower = 1; move.IsBrake = false; return true; }
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; }