/* * Проверка что кто-то стоит впереди * p2 p5 p3 p4 p1 * | | | | | * o-----------------o * | | * | | */ public bool IsSomeoneAhead(ACar car, int direction) { var carRect = car.GetRect(0); Point p1, p2; if (direction > 0) { p1 = carRect[0] + Point.ByAngle(car.Angle) * 20; p2 = carRect[3] + Point.ByAngle(car.Angle) * 20; } else { p1 = carRect[1] - Point.ByAngle(car.Angle) * 20; p2 = carRect[2] - Point.ByAngle(car.Angle) * 20; } var p3 = (p1 + p2) / 2; var p4 = (p1 + p3) / 2; var p5 = (p2 + p3) / 2; return(world.Cars.Select(x => new ACar(x).GetRect(0)).Any( rect => Geom.ContainPoint(rect, p1) || Geom.ContainPoint(rect, p2) || Geom.ContainPoint(rect, p3) || Geom.ContainPoint(rect, p4) || Geom.ContainPoint(rect, p5) )); }
public AOilSlick(ACar car) { var dist = Const.Game.OilSlickInitialRange + car.Original.Width / 2 + Const.Game.OilSlickRadius; var slick = car - Point.ByAngle(car.Angle) * dist; X = slick.X; Y = slick.Y; Radius = Const.Game.OilSlickRadius; RemainingLifetime = Const.Game.OilSlickLifetime; }
public static AProjectile[] GetProjectiles(ACar car) { if (car.Original.Type == CarType.Jeep) { return(new[] { new AProjectile { Radius = Const.Game.TireRadius, Type = ProjectileType.Tire, X = car.X, Y = car.Y, Speed = Point.ByAngle(car.Angle) * Const.Game.TireInitialSpeed } }); } return(new[] { 0.0, -Const.Game.SideWasherAngle, Const.Game.SideWasherAngle }.Select(angle => new AProjectile { Radius = Const.Game.WasherRadius, Type = ProjectileType.Washer, X = car.X, Y = car.Y, Speed = Point.ByAngle(angle + car.Angle) * Const.Game.WasherInitialSpeed }).ToArray()); }
public void Move(double enginePower, double wheelTurn, bool isBreak, bool useNitro, bool simpleMode) { if (RemainingInactiveTicks > 0 || MyStrategy.IsCrashed(Original)) { isBreak = false; useNitro = false; enginePower = 0; wheelTurn = WheelTurn; } useNitro = useNitro && Original.NitroChargeCount > 0; if (useNitro && RemainingNitroTicks == 0 && RemainingNitroCooldownTicks == 0) { RemainingNitroTicks = Const.Game.NitroDurationTicks; RemainingNitroCooldownTicks = Const.Game.UseNitroCooldownTicks; } var updateIterations = simpleMode ? 2 : 10; var frictionMultiplier = Math.Pow(1.0 - Const.Game.CarMovementAirFrictionFactor, 1.0 / updateIterations); var rotationFrictionMultiplier = Math.Pow(1.0 - Const.Game.CarRotationFrictionFactor, 1.0 / updateIterations); if (enginePower > 1 + MyStrategy.Eps || enginePower < -1 - MyStrategy.Eps) { throw new Exception("invalid enginePower " + enginePower); } if (wheelTurn > 1 + MyStrategy.Eps || wheelTurn < -1 - MyStrategy.Eps) { throw new Exception("invalid wheelTurn " + wheelTurn); } if (RemainingNitroTicks > 0) { EnginePower = 2.0; } else { EnginePower = enginePower > EnginePower ? Math.Min(EnginePower + Const.Game.CarEnginePowerChangePerTick, enginePower) : Math.Max(EnginePower - Const.Game.CarEnginePowerChangePerTick, enginePower); } WheelTurn = wheelTurn > WheelTurn ? Math.Min(WheelTurn + Const.Game.CarWheelTurnChangePerTick, wheelTurn) : Math.Max(WheelTurn - Const.Game.CarWheelTurnChangePerTick, wheelTurn); if (MyStrategy.world.Tick >= Const.Game.InitialFreezeDurationTicks) { // http://russianaicup.ru/forum/index.php?topic=394.msg3888#msg3888 var dir = Point.ByAngle(Angle); var baseAngSpd = AngularSpeed; // HACK AngularSpeed -= baseAngSpd; baseAngSpd = Const.Game.CarAngularSpeedFactor * WheelTurn * (Speed * dir); AngularSpeed += baseAngSpd; var carAcceleration = EnginePower >= 0 ? _carAccelerationUp : _carAccelerationDown; var accelerationDelta = dir * (carAcceleration * EnginePower / updateIterations); var lengthwiseMovementFrictionFactor = isBreak ? Const.Game.CarCrosswiseMovementFrictionFactor : Const.Game.CarLengthwiseMovementFrictionFactor; lengthwiseMovementFrictionFactor /= updateIterations; var crosswiseMovementFrictionFactor = Const.Game.CarCrosswiseMovementFrictionFactor / updateIterations; for (var i = 0; i < updateIterations; i++) { X += Speed.X / updateIterations; Y += Speed.Y / updateIterations; if (!isBreak) { Speed.X += accelerationDelta.X; Speed.Y += accelerationDelta.Y; } Speed.X *= frictionMultiplier; Speed.Y *= frictionMultiplier; var t1 = _limit(Speed.X * dir.X + Speed.Y * dir.Y, lengthwiseMovementFrictionFactor); var t2 = _limit(Speed.X * dir.Y - Speed.Y * dir.X, crosswiseMovementFrictionFactor); Speed.X = dir.X * t1 + dir.Y * t2; Speed.Y = dir.Y * t1 - dir.X * t2; Angle += AngularSpeed / updateIterations; dir = Point.ByAngle(Angle); AngularSpeed = baseAngSpd + (AngularSpeed - baseAngSpd) * rotationFrictionMultiplier; } Geom.AngleNormalize(ref Angle); if (RemainingNitroCooldownTicks > 0) { RemainingNitroCooldownTicks--; } if (RemainingNitroTicks > 0) { RemainingNitroTicks--; } if (RemainingInactiveTicks > 0) { RemainingInactiveTicks--; } } // clear rectangles cache _rect = null; _rectEx = null; }
public static void Draw() { if (_form.InvokeRequired) { _form.BeginInvoke(new DrawDelegate(Draw), new object[] { }); return; } _renderTick++; if ((_renderTick - 1) % _myCarsCount != _myCarsCount - 1) { return; } var panel = _form.panel; _form.tickLabel.Text = MyStrategy.world.Tick + ""; var drawArea = new Bitmap(panel.Size.Width, panel.Size.Height); panel.Image = drawArea; _graphics = Graphics.FromImage(drawArea); if (_myCarsCount == 1) { _form.jeepRadioButton.Enabled = false; _form.buggyRadioButton.Enabled = false; LookUp(new Point(MyStrategy.world.Cars.FirstOrDefault(x => x.IsTeammate))); } else { LookUp( new Point( MyStrategy.world.Cars.FirstOrDefault( x => x.IsTeammate && (x.Type == CarType.Jeep && _form.jeepRadioButton.Checked || x.Type == CarType.Buggy && _form.buggyRadioButton.Checked)))); } //var myNextWp = MyStrategy.GetNextWayPoint(self); //FillRect(Brushes.Aqua, myNextWp.J * Const.TileSize, myNextWp.I * Const.TileSize, Const.TileSize, Const.TileSize); // tiles foreach (var tile in MyStrategy.MyTiles) { var margin = Const.TileMargin; var tsize = Const.TileSize; var dx = Const.TileSize * tile.J; var dy = Const.TileSize * tile.I; if (tile.Type == TileType.Unknown) { FillRect(Brushes.DarkGray, dx, dy, tsize, tsize); } if (tile.Type == TileType.Empty) { FillRect(Brushes.Black, dx, dy, tsize, tsize); } if (!tile.IsFreeLeft) { FillRect(Brushes.Black, dx, dy, margin, tsize); } if (!tile.IsFreeTop) { FillRect(Brushes.Black, dx, dy, tsize, margin); } if (!tile.IsFreeRight) { FillRect(Brushes.Black, dx + tsize - margin, dy, margin, tsize); } if (!tile.IsFreeBottom) { FillRect(Brushes.Black, dx, dy + tsize - margin, tsize, margin); } foreach (var part in tile.Parts) { switch (part.Type) { case TilePartType.Circle: FillCircle(Brushes.Black, part.Circle.X, part.Circle.Y, part.Circle.Radius); break; case TilePartType.Segment: DrawLine(Brushes.DarkRed, part.Start.X, part.Start.Y, part.End.X, part.End.Y, 1); break; default: throw new Exception("Unknown TilePartType"); } } } // Bonuses foreach (var bonus in MyStrategy.world.Bonuses) { var rect = new ABonus(bonus).GetRect(); for (var i = 0; i < 4; i++) { Brush brush; if (bonus.Type == BonusType.PureScore) { brush = Brushes.OrangeRed; } else if (bonus.Type == BonusType.RepairKit) { brush = Brushes.LimeGreen; } else if (bonus.Type == BonusType.OilCanister) { brush = Brushes.DarkSlateGray; } else if (bonus.Type == BonusType.NitroBoost) { brush = Brushes.Blue; } else if (bonus.Type == BonusType.AmmoCrate) { brush = Brushes.DarkGoldenrod; } else { throw new Exception("Unknown BonusType"); } DrawLine(brush, rect[i].X, rect[i].Y, rect[(i + 1) % 4].X, rect[(i + 1) % 4].Y, 2); } } // Cars foreach (var car in MyStrategy.world.Cars) { var isAvtive = DurabilityObserver.IsActive(car); var rect = new ACar(car).GetRectEx(isAvtive ? 0 : 1); for (var i = 0; i < 4; i++) { DrawLine(car.IsTeammate ? Brushes.Green : Brushes.Red, rect[i].X, rect[i].Y, rect[(i + 1) % 4].X, rect[(i + 1) % 4].Y, isAvtive ? 2 : 1); } var to = Point.ByAngle(car.Angle) * 100 + new Point(car); DrawLine(Brushes.Black, car.X, car.Y, to.X, to.Y, car.Type == CarType.Buggy ? 2 : 6); DrawText("~" + car.ProjectileCount, 50, Brushes.Black, car.X, car.Y); } // Oil foreach (var stick in MyStrategy.world.OilSlicks) { FillCircle(Brushes.Black, stick.X, stick.Y, stick.Radius); } // Nitro foreach (var car in MyStrategy.world.Cars) { if (car.RemainingNitroTicks > 0) { FillCircle(Brushes.Blue, car.X, car.Y, 40); } } // Canisters foreach (var car in MyStrategy.world.Cars) { if (car.OilCanisterCount == 0) { continue; } var canisterPen = car.RemainingOilCooldownTicks == 0 ? Pens.DarkSlateGray : Pens.Lavender; var slick = new AOilSlick(new ACar(car)); DrawCircle(canisterPen, slick.X, slick.Y, slick.Radius); if (car.RemainingOiledTicks > 0) { FillCircle(Brushes.Black, car.X, car.Y, 30); } } // Projectiles foreach (var pr in MyStrategy.world.Projectiles) { FillCircle(Brushes.OrangeRed, pr.X, pr.Y, pr.Radius); } // Segments try { foreach (var _el in SegmentsDrawQueue) { var el = _el as object[]; var brush = el[0] as Brush; var line = el[1] as Points; var width = Convert.ToDouble(el[2]); for (var i = 1; i < line.Count; i++) { DrawLine(brush, line[i - 1].X, line[i - 1].Y, line[i].X, line[i].Y, (float)width); } } } catch (Exception) { } // Circles foreach (var el in CircleFillQueue) { var brush = el.Item1; var circle = el.Item2; FillCircle(brush, circle.X, circle.Y, circle.Radius); } CircleFillQueue.Clear(); SegmentsDrawQueue.Clear(); }