private void CalculateEnemiesBehind(Car self, Game game) { foreach (var car in this.enemiesCars) { if (!car.IsFinishedTrack && car.Durability > 0.0) { var currentPosition = new PointF((float)car.X, (float)car.Y); var nextPosition = new PointF((float)car.X + (float)car.SpeedX, (float)car.Y + (float)car.SpeedY); var futurePosition = new PointF( (float)car.X + PredictionCount * (float)car.SpeedX, (float)car.Y + PredictionCount * (float)car.SpeedY); var xOffset = (float) (Math.Cos(self.Angle) * (game.CarHeight + game.OilSlickInitialRange + game.OilSlickRadius)); var yOffset = (float) (Math.Sin(self.Angle) * (game.CarHeight + game.OilSlickInitialRange + game.OilSlickRadius)); var oilPosition = new PointF((float)self.X + xOffset, (float)self.Y - yOffset); float distance = MathHelper.DistanceToLine(oilPosition, currentPosition, futurePosition); if (distance < game.OilSlickRadius + game.CarWidth / 2 && MathHelper.Distance(currentPosition, oilPosition) < game.OilSlickRadius + PredictionCount * car.GetSpeed() && MathHelper.Distance(currentPosition, oilPosition) > MathHelper.Distance(nextPosition, oilPosition)) { this.enemyBehind = true; break; } } } }
public static float DistanceToLine(PointF targetPoint, PointF linePoint1, PointF linePoint2) { return (float) Math.Abs( ((linePoint1.Y - linePoint2.Y) * targetPoint.X + (linePoint2.X - linePoint1.X) * targetPoint.Y + linePoint1.X * linePoint2.Y - linePoint2.X * linePoint2.Y) / Distance(linePoint1, linePoint2)); }
public static PointF? PointOfIntersection( PointF line1Point1, PointF line1Point2, PointF line2Point1, PointF line2Point2) { float a1 = line1Point2.Y - line1Point1.Y; float b1 = line1Point1.X - line1Point2.X; float c1 = -((line1Point2.X - line1Point1.X) * line1Point1.Y - (line1Point2.Y - line1Point1.Y) * line1Point1.X); float a2 = line2Point2.Y - line2Point1.Y; float b2 = line2Point1.X - line2Point2.X; float c2 = -((line2Point2.X - line2Point1.X) * line2Point1.Y - (line2Point2.Y - line2Point1.Y) * line2Point1.X); float det = a1 * b2 - b1 * a2; if (Math.Abs(det) < 1e-5) { return null; } float d1 = c1 * b2 - b1 * c2; float d2 = a1 * c2 - c1 * a2; return new PointF(d1 / det, d2 / det); }
private void BuildRealPath() { int horLength = map.GetLength(0); int vertLength = map.GetLength(1); Point currentPosition = Point.Empty; Point destination = Point.Empty; for (int i = 0; i < horLength; i++) { for (int j = 0; j < vertLength; j++) { if (this.mapWithIdealPath[i, j] == MyRoadType.CurrentPosition) { currentPosition = new Point(i, j); } if (this.mapWithIdealPath[i, j] == MyRoadType.Destination) { destination = new Point(i, j); } } } HashSet<Point> usedPoints = new HashSet<Point>(); List<Point> currentLevel = new List<Point> { destination }; List<Point> nextLevel = new List<Point>(); Action<Point> addIfIdeal = p => { if (p.X >= 0 && p.X < horLength && p.Y >= 0 && p.Y < vertLength && this.mapWithIdealPath[p.X, p.Y] == MyRoadType.IdealPath) { nextLevel.Add(p); } }; while (true) { foreach (var point in currentLevel) { if (!usedPoints.Contains(point)) { if (CanDriveFromTo(currentPosition, point)) { this.nextPoint = new PointF((point.X + 0.5f) * MyTileSize, (point.Y + 0.5f) * MyTileSize); return; } usedPoints.Add(point); addIfIdeal(new Point(point.X - 1, point.Y - 1)); addIfIdeal(new Point(point.X, point.Y - 1)); addIfIdeal(new Point(point.X + 1, point.Y - 1)); addIfIdeal(new Point(point.X - 1, point.Y)); addIfIdeal(new Point(point.X + 1, point.Y)); addIfIdeal(new Point(point.X - 1, point.Y + 1)); addIfIdeal(new Point(point.X, point.Y + 1)); addIfIdeal(new Point(point.X + 1, point.Y + 1)); } } if (nextLevel.Count == 0) { break; } currentLevel.Clear(); currentLevel.AddRange(nextLevel); nextLevel.Clear(); } // TODO: We should not be here but we are. Fix this!!! this.nextPoint = new PointF((destination.X + 0.5f) * MyTileSize, (destination.Y + 0.5f) * MyTileSize); }
private Point GetNextWaypoint(Car self, Game game, World world) { var nextWayPoint = new PointF( (self.NextWaypointX + 0.5f) * (float)game.TrackTileSize, (self.NextWaypointY + 0.5f) * (float)game.TrackTileSize); float cornerTileOffset = 0.225f * (float)game.TrackTileSize; switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY]) { case TileType.LeftBottomCorner: nextWayPoint.X += cornerTileOffset; nextWayPoint.Y -= cornerTileOffset; break; case TileType.LeftTopCorner: nextWayPoint.X += cornerTileOffset; nextWayPoint.Y += cornerTileOffset; break; case TileType.RightBottomCorner: nextWayPoint.X -= cornerTileOffset; nextWayPoint.Y -= cornerTileOffset; break; case TileType.RightTopCorner: nextWayPoint.X -= cornerTileOffset; nextWayPoint.Y += cornerTileOffset; break; case TileType.BottomHeadedT: nextWayPoint.Y += cornerTileOffset; break; case TileType.TopHeadedT: nextWayPoint.Y -= cornerTileOffset; break; case TileType.LeftHeadedT: nextWayPoint.X -= cornerTileOffset; break; case TileType.RightHeadedT: nextWayPoint.X += cornerTileOffset; break; } return new Point((int)nextWayPoint.X / MyTileSize, (int)nextWayPoint.Y / MyTileSize); }
private void FindPath(Car self, World world, Game game) { this.BuildMap(world, game); this.BuildIdealPath(self, game, world); int horLength = map.GetLength(0); int vertLength = map.GetLength(1); bool step34AreNecessary = false; for (int i = 0; i < horLength && !step34AreNecessary; i++) { for (int j = 0; j < vertLength; j++) { if (this.mapWithIdealPath[i, j] == MyRoadType.IdealPath && map[i, j] == MyTileType.Red) { step34AreNecessary = true; break; } } } if (step34AreNecessary) { AvoidObstacles(); BuildRealPath(); } else { this.nextPoint = new PointF( (self.NextWaypointX + 0.5f) * (float)game.TrackTileSize, (self.NextWaypointY + 0.5f) * (float)game.TrackTileSize); bool nextPointFound = false; for (int i = 0; i < horLength && !nextPointFound; i++) { for (int j = 0; j < vertLength; j++) { if (this.mapWithIdealPath[i, j] == MyRoadType.Destination) { this.nextPoint = new PointF((i + 0.5f) * MyTileSize, (j + 0.5f) * MyTileSize); nextPointFound = true; break; } } } } }
public static Point Truncate(PointF value) { return new Point((int)value.X, (int)value.Y); }
public static Point Round(PointF value) { return new Point((int)Math.Round(value.X), (int)Math.Round(value.Y)); }
public static Point Ceiling(PointF value) { return new Point((int)Math.Ceiling(value.X), (int)Math.Ceiling(value.Y)); }
private void CalculateEnemiesInFront(Car self, Game game) { foreach (var car in this.enemiesCars) { if (car.Type == CarType.Buggy) { if (!car.IsFinishedTrack && car.Durability > 0.0) { var currentEnemyPosition = new PointF((float)car.X, (float)car.Y); var nextEnemyPosition = new PointF( (float)car.X + (float)car.SpeedX, (float)car.Y + (float)car.SpeedY); var futureEnemyPosition = new PointF( (float)car.X + PredictionCount * (float)car.SpeedX, (float)car.Y + PredictionCount * (float)car.SpeedY); var currentWasherPosition = new PointF((float)self.X, (float)self.Y); var nextWasherPosition = new PointF( (float)self.X + (float)self.SpeedX / self.GetSpeed() * (float)game.WasherInitialSpeed, (float)self.Y + (float)self.SpeedY / self.GetSpeed() * (float)game.WasherInitialSpeed); var futureWasherPosition = new PointF( (float)self.X + PredictionCount * (float)self.SpeedX / self.GetSpeed() * (float)game.WasherInitialSpeed, (float)self.Y + PredictionCount * (float)self.SpeedY / self.GetSpeed() * (float)game.WasherInitialSpeed); PointF? intersectsPoint = MathHelper.PointOfIntersection( currentWasherPosition, futureWasherPosition, currentEnemyPosition, futureEnemyPosition); if (intersectsPoint.HasValue && MathHelper.Distance(intersectsPoint.Value, currentWasherPosition) / (float)game.WasherInitialSpeed <= PredictionCount && MathHelper.Distance(currentWasherPosition, currentEnemyPosition) > MathHelper.Distance(nextWasherPosition, nextEnemyPosition) && Math.Abs( MathHelper.Distance(intersectsPoint.Value, currentWasherPosition) / (float)game.WasherInitialSpeed - MathHelper.Distance(intersectsPoint.Value, currentEnemyPosition) / car.GetSpeed()) < WasherPredictionError) { this.enemyInFront = true; break; } } } } }
public static float Distance(PointF point1, PointF point2) { return (float) Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y)); }
public static PointF Add(PointF pt, Size sz) { return new PointF(pt.X + (float)sz.Width, pt.Y + (float)sz.Height); }
public static PointF Subtract(PointF pt, SizeF sz) { return new PointF(pt.X - sz.Width, pt.Y - sz.Height); }
public static PointF Add(PointF pt, SizeF sz) { return new PointF(pt.X + sz.Width, pt.Y + sz.Height); }
public SizeF(PointF pt) { width = pt.X; height = pt.Y; }