Example #1
0
        void AlternativeMove(Points pts)
        {
            var car = new ACar(self);

            var backBruteRes = _doAndSelectBrute(BackBrutes, pts);

            if (backBruteRes.Item1 != -1)
            {
                BackBrutes[backBruteRes.Item1].SelectThis();
                var mv = backBruteRes.Item2[backBruteRes.Item1];
                if (mv.Count > 0)
                {
                    mv[0].Apply(move, new ACar(self));
                    ComputedPath[self.Id] = GetCarPath(self, mv);
#if DEBUG
                    Visualizer.DrawWays(self, backBruteRes.Item2, backBruteRes.Item1);
#endif
                    return;
                }
            }

            // change points
            pts = GetAlternativeWaySegments(self);
            var turnCenter = pts[1];

            var tmp = new ACar(self);
            var aa  = tmp + tmp.Speed;
            if (Math.Abs(tmp.GetAngleTo(aa)) > Math.PI / 2)
            {
                move.EnginePower = 1;
                move.WheelTurn  *= -1;
                return;
            }


            move.EnginePower = 1.0;

            if (car.GetDistanceTo(turnCenter) < 1.6 * Const.TileSize)
            {
                move.EnginePower = 0.8;
            }

            if (car.GetDistanceTo(turnCenter) < 1.0 * Const.TileSize)
            {
                if (GetSpeed(self) > 11)
                {
                    move.IsBrake = true;
                }
            }
            move.WheelTurn = car.GetAngleTo(turnCenter);

            if (BAD_TESTING_STRATEGY)
            {
                if (turnCenter.GetDistanceTo(self) >= 7 * Const.TileSize &&
                    Math.Abs(car.GetAngleTo(turnCenter)) < Math.PI / 6)
                {
                    move.IsUseNitro = true;
                }
            }
        }
Example #2
0
        private void _carMoveFunc(ACar model, int from, int to, int step, AMove m, PassedInfo passed, CarCallback callback)
        {
            model   = model.Clone();
            passed  = passed.Clone();
            m.Times = 0;

            for (var t = 0; t < from; t++)
            {
                if (!_modelMove(model, m, passed))
                {
                    return;
                }
                m.Times++;
            }

            for (var t = from; t <= to; t += step)
            {
                _movesStack.Add(m);
                callback(model, passed);
                _movesStack.Pop();
                for (var r = 0; r < step; r++)
                {
                    if (!_modelMove(model, m, passed))
                    {
                        return;
                    }
                    m.Times++;
                }
            }
        }
Example #3
0
        /*
         * Проверка что кто-то стоит впереди
         * 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)
                       ));
        }
Example #4
0
File: ACar.cs Project: znsoft/AiCup
 public bool IntersectWith(ACar car, double safeMargin)
 {
     if (GetDistanceTo2(car) > Geom.Sqr(Const.CarDiagonalHalfLength + Const.CarDiagonalHalfLength))
     {
         return(false);
     }
     return(Geom.PolygonsIntersect(GetRect(0), car.GetRect(safeMargin)));
 }
Example #5
0
 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;
 }
Example #6
0
        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;
        }
Example #7
0
        public bool Intersect(ACar car, double extendRadius)
        {
            if (Type == ProjectileType.Washer)
                return Geom.ContainPoint(car.GetRect(-extendRadius), this);

            var r = Radius + extendRadius;
            if (GetDistanceTo2(car) > Geom.Sqr(r + Const.CarDiagonalHalfLength))
                return false;

            return car.GetRectEx().Any(p => GetDistanceTo(p) < r);
        }
Example #8
0
        public bool Intersect(ACar car, double extendRadius)
        {
            if (Type == ProjectileType.Washer)
            {
                return(Geom.ContainPoint(car.GetRect(-extendRadius), this));
            }

            var r = Radius + extendRadius;

            if (GetDistanceTo2(car) > Geom.Sqr(r + Const.CarDiagonalHalfLength))
            {
                return(false);
            }

            return(car.GetRectEx().Any(p => GetDistanceTo(p) < r));
        }
Example #9
0
        bool CheckBackMove(Point turnCenter)
        {
            const int ticksToCheck = 40;

            for (var power = -1; power <= 1; power += 2)
            {
                if (BackModeRemainTicks == 0 && PositionsHistory.Count > ticksToCheck)
                {
                    if (
                        PositionsHistory[PositionsHistory.Count - 1].GetDistanceTo(
                            PositionsHistory[PositionsHistory.Count - ticksToCheck]) < 20)
                    {
                        var model = new ACar(self)
                        {
                            EnginePower = -power
                        };
                        var cnt = 0;
                        for (var i = 0; i < 80; i++)
                        {
                            if (ModelMove(model, new AMove {
                                EnginePower = -power, IsBrake = false, WheelTurn = 0
                            },
                                          simpleMode: false, exactlyBorders: true))
                            {
                                cnt++;
                            }
                        }
                        if (cnt < 25 || IsSomeoneAhead(new ACar(self), -power))
                        {
                            BackModeRemainTicks = 50;
                            BackModeTurn        = self.GetAngleTo(turnCenter.X, turnCenter.Y) < 0 ? -power : power;
                            BackModePower       = power;
                            break;
                        }
                    }
                }
            }
            if (BackModeRemainTicks > 0)
            {
                BackModeRemainTicks--;
                move.EnginePower = BackModePower;
                move.WheelTurn   = BackModeTurn;
                return(true);
            }
            return(false);
        }
Example #10
0
        public static ACar[] GetCarPath(Car self, Moves stack)
        {
            if (stack == null)
                return null;

            stack = stack.Clone();
            var res = new List<ACar>();
            var model = new ACar(self);
            while (stack.Count > 0)
            {
                var m = stack[0];
                AMove.ModelMove(model, m, new PassedInfo(), Bonuses, OilSlicks, Tires, Others);
                m.Times--;
                stack.Normalize();
                res.Add(model.Clone());
            }
            return res.ToArray();
        }
Example #11
0
        public void PrepareOpponentsPath()
        {
            if (world.Tick < Const.Game.InitialFreezeDurationTicks)
            {
                return;
            }

            TimerStart();
            var ways = Opponents.Select(GetWaySegments).ToArray();

#if DEBUG
            var segs = Opponents.Select(x => new Points()).ToArray();
#endif

            OpponentsCars = new ACar[Opponents.Length][];
            for (var i = 0; i < Opponents.Length; i++)
            {
                if (ComputedPath.ContainsKey(Opponents[i].Id))
                {
                    OpponentsCars[i] = ComputedPath[Opponents[i].Id];
                }
                else
                {
                    OpponentsCars[i]    = new ACar[MagicConst.OpponentsTicksPrediction];
                    OpponentsCars[i][0] = new ACar(Opponents[i]);
                    for (var t = 1; t < MagicConst.OpponentsTicksPrediction; t++)
                    {
                        OpponentsCars[i][t] = OpponentsCars[i][t - 1].Clone();
                        _simulateOpponentMove(ways[i], OpponentsCars[i][t]);
#if DEBUG
                        segs[i].Add(new Point(OpponentsCars[i][t]));
#endif
                    }
                }
            }

#if DEBUG
            foreach (var seg in segs)
            {
                Visualizer.SegmentsDrawQueue.Add(new object[] { Brushes.Indigo, seg, 0.0 });
            }
#endif
            TimerEndLog("PrepareOpponentsPath");
        }
Example #12
0
        public double ComputeImportance(ACar model)
        {
            model = model.Clone();
            var total = new PassedInfo();

            foreach (var move in this)
            {
                for (var t = 0; t < move.Times; t++)
                {
                    _modelMove(model, move, total);
                }
            }
#if DEBUG
            if (ComputeTime() != total.Time)
            {
                throw new Exception("ComputeTime() != elapsedTime");
            }
#endif
            return(total.Time - total.Importance + Penalty);
        }
Example #13
0
        private void _simulateOpponentMove(Points pts, ACar car)
        {
            if (car.OutOfMap)
            {
                return;
            }

            if (pts.Count == 0)
            {
                Log("need more points!");
                return;
            }
            var p = pts[0];

            if (car.GetDistanceTo2(p) < 500 * 500)
            {
                pts.RemoveAt(0);
                _simulateOpponentMove(pts, car);
                return;
            }
            var turn  = car.GetAngleTo(p);
            var power = 1.0;

            if (Math.Abs(turn) > 0.5)
            {
                power = 0.5;
            }
            if (Math.Abs(turn) > 1)
            {
                power = 0.3;
            }

            if (!ModelMove(car,
                           new AMove {
                EnginePower = power, IsBrake = false, WheelTurn = TurnRound(turn)
            },
                           simpleMode: true))
            {
                car.OutOfMap = true;
            }
        }
Example #14
0
File: ACar.cs Project: znsoft/AiCup
        public ACar(ACar car)
        {
            X = car.X;
            Y = car.Y;
            Original = car.Original;
            Speed = car.Speed.Clone();
            Angle = car.Angle;
            EnginePower = car.EnginePower;
            WheelTurn = car.WheelTurn;
            AngularSpeed = car.AngularSpeed;
            OutOfMap = car.OutOfMap;
            RemainingNitroTicks = car.RemainingNitroTicks;
            RemainingNitroCooldownTicks = car.RemainingNitroCooldownTicks;
            RemainingInactiveTicks = car.RemainingInactiveTicks;

            Width = car.Width;
            Height = car.Height;

            _carAccelerationUp = car._carAccelerationUp;
            _carAccelerationDown = car._carAccelerationDown;
        }
Example #15
0
        public static ACar[] GetCarPath(Car self, Moves stack)
        {
            if (stack == null)
            {
                return(null);
            }

            stack = stack.Clone();
            var res   = new List <ACar>();
            var model = new ACar(self);

            while (stack.Count > 0)
            {
                var m = stack[0];
                AMove.ModelMove(model, m, new PassedInfo(), Bonuses, OilSlicks, Tires, Others);
                m.Times--;
                stack.Normalize();
                res.Add(model.Clone());
            }
            return(res.ToArray());
        }
Example #16
0
        public void Apply(Move move, ACar car)
        {
            move.EnginePower = EnginePower;
            move.IsBrake     = IsBrake;
            move.WheelTurn   = WheelTurn is Point?MyStrategy.TurnRound(car.GetAngleTo(WheelTurn as Point)) : Convert.ToDouble(WheelTurn);

            if (EnginePower < 0 && car.EnginePower > 0)
            {
                move.IsBrake = true;
            }
            else if (car.EnginePower < 0 && EnginePower > 0)
            {
                move.WheelTurn *= -1;
                move.IsBrake    = true;
            }

            if (IsUseNitro)
            {
                move.IsUseNitro = IsUseNitro;
            }
        }
Example #17
0
File: ACar.cs Project: znsoft/AiCup
        public ACar(ACar car)
        {
            X                           = car.X;
            Y                           = car.Y;
            Original                    = car.Original;
            Speed                       = car.Speed.Clone();
            Angle                       = car.Angle;
            EnginePower                 = car.EnginePower;
            WheelTurn                   = car.WheelTurn;
            AngularSpeed                = car.AngularSpeed;
            OutOfMap                    = car.OutOfMap;
            RemainingNitroTicks         = car.RemainingNitroTicks;
            RemainingNitroCooldownTicks = car.RemainingNitroCooldownTicks;
            RemainingInactiveTicks      = car.RemainingInactiveTicks;

            Width  = car.Width;
            Height = car.Height;

            _carAccelerationUp   = car._carAccelerationUp;
            _carAccelerationDown = car._carAccelerationDown;
        }
Example #18
0
        private void _validateLastSuccessStack()
        {
            if (_lastSuccessStack == null)
            {
                return;
            }
            var car   = new ACar(Self);
            var stack = _lastSuccessStack.Clone();
            var info  = new PassedInfo();

            while (stack.Count > 0)
            {
                if (!AMove.ModelMove(car, stack[0], info,
                                     new ABonus[] {}, new AOilSlick[] {}, new AProjectile[][] {}, new ACar[][] {}))
                {
                    _lastSuccessStack = null;
                    return;
                }
                stack[0].Times--;
                stack.Normalize();
            }
        }
Example #19
0
        public static bool ModelMove(ACar car, AMove m, bool simpleMode = false, bool exactlyBorders = false)
        {
            var prevStateX     = car.X;
            var prevStateY     = car.Y;
            var prevStateAngle = car.Angle;

            var turn = m.WheelTurn is Point?TurnRound(car.GetAngleTo(m.WheelTurn as Point)) : Convert.ToDouble(m.WheelTurn);

            car.Move(m.EnginePower, turn, m.IsBrake, m.IsUseNitro, simpleMode);
            var ok = car.GetRect(0).All(p => !IntersectTail(p, exactlyBorders ? 0 : MagicConst.SafeMargin));

            if (!ok)
            {
                // HACK
                car.X            = prevStateX;
                car.Y            = prevStateY;
                car.Angle        = prevStateAngle;
                car.Speed        = Point.Zero;
                car.AngularSpeed = 0;
            }
            return(ok);
        }
Example #20
0
        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();
        }
Example #21
0
        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());
        }
Example #22
0
 public bool Intersect(ACar car, double safeMargin)
 {
     return GetDistanceTo2(car) < Geom.Sqr(Radius + safeMargin);
 }
Example #23
0
        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();
        }
Example #24
0
 private void _validateLastSuccessStack()
 {
     if (_lastSuccessStack == null)
         return;
     var car = new ACar(Self);
     var stack = _lastSuccessStack.Clone();
     var info = new PassedInfo();
     while (stack.Count > 0)
     {
         if (!AMove.ModelMove(car, stack[0], info,
             new ABonus[] {}, new AOilSlick[] {}, new AProjectile[][] {}, new ACar[][] {}))
         {
             _lastSuccessStack = null;
             return;
         }
         stack[0].Times--;
         stack.Normalize();
     }
 }
Example #25
0
        private void _carMoveFunc(ACar model, int from, int to, int step, AMove m, PassedInfo passed, CarCallback callback)
        {
            model = model.Clone();
            passed = passed.Clone();
            m.Times = 0;

            for (var t = 0; t < from; t++)
            {
                if (!_modelMove(model, m, passed))
                    return;
                m.Times++;
            }

            for (var t = from; t <= to; t += step)
            {
                _movesStack.Add(m);
                callback(model, passed);
                _movesStack.Pop();
                for (var r = 0; r < step; r++)
                {
                    if (!_modelMove(model, m, passed))
                        return;
                    m.Times++;
                }
            }
        }
Example #26
0
        public static bool ModelMove(ACar car, AMove m, bool simpleMode = false, bool exactlyBorders = false)
        {
            var prevStateX = car.X;
            var prevStateY = car.Y;
            var prevStateAngle = car.Angle;

            var turn = m.WheelTurn is Point ? TurnRound(car.GetAngleTo(m.WheelTurn as Point)) : Convert.ToDouble(m.WheelTurn);
            car.Move(m.EnginePower, turn, m.IsBrake, m.IsUseNitro, simpleMode);
            var ok = car.GetRect(0).All(p => !IntersectTail(p, exactlyBorders ? 0 : MagicConst.SafeMargin));
            if (!ok)
            {
                // HACK
                car.X = prevStateX;
                car.Y = prevStateY;
                car.Angle = prevStateAngle;
                car.Speed = Point.Zero;
                car.AngularSpeed = 0;
            }
            return ok;
        }
Example #27
0
        private void _simulateOpponentMove(Points pts, ACar car)
        {
            if (car.OutOfMap)
                return;

            if (pts.Count == 0)
            {
                Log("need more points!");
                return;
            }
            var p = pts[0];
            if (car.GetDistanceTo2(p) < 500 * 500)
            {
                pts.RemoveAt(0);
                _simulateOpponentMove(pts, car);
                return;
            }
            var turn = car.GetAngleTo(p);
            var power = 1.0;
            if (Math.Abs(turn) > 0.5)
                power = 0.5;
            if (Math.Abs(turn) > 1)
                power = 0.3;

            if (!ModelMove(car,
                new AMove {EnginePower = power, IsBrake = false, WheelTurn = TurnRound(turn)},
                simpleMode: true))
            {
                car.OutOfMap = true;
            }
        }
Example #28
0
        public void PrepareOpponentsPath()
        {
            if (world.Tick < Const.Game.InitialFreezeDurationTicks)
                return;

            TimerStart();
            var ways = Opponents.Select(GetWaySegments).ToArray();
            #if DEBUG
            var segs = Opponents.Select(x => new Points()).ToArray();
            #endif

            OpponentsCars = new ACar[Opponents.Length][];
            for (var i = 0; i < Opponents.Length; i++)
            {
                if (ComputedPath.ContainsKey(Opponents[i].Id))
                    OpponentsCars[i] = ComputedPath[Opponents[i].Id];
                else
                {
                    OpponentsCars[i] = new ACar[MagicConst.OpponentsTicksPrediction];
                    OpponentsCars[i][0] = new ACar(Opponents[i]);
                    for (var t = 1; t < MagicConst.OpponentsTicksPrediction; t++)
                    {
                        OpponentsCars[i][t] = OpponentsCars[i][t - 1].Clone();
                        _simulateOpponentMove(ways[i], OpponentsCars[i][t]);
            #if DEBUG
                        segs[i].Add(new Point(OpponentsCars[i][t]));
            #endif
                    }
                }
            }

            #if DEBUG
            foreach (var seg in segs)
                Visualizer.SegmentsDrawQueue.Add(new object[] { Brushes.Indigo, seg, 0.0 });
            #endif
            TimerEndLog("PrepareOpponentsPath");
        }
Example #29
0
 public bool Intersect(ACar car, double safeMargin)
 {
     return(GetDistanceTo2(car) < Geom.Sqr(Radius + safeMargin));
 }
Example #30
0
 private bool _modelMove(ACar car, AMove m, PassedInfo total)
 {
     return(AMove.ModelMove(car, m, total,
                            MyStrategy.Bonuses, MyStrategy.OilSlicks, MyStrategy.Tires, MyStrategy.Others));
 }
Example #31
0
        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();
        }
Example #32
0
        public Moves Do(ACar car, Points pts)
        {
            // Проверка что данный путь был выбран
            if (_selectThisTick + 1 != MyStrategy.world.Tick)
                _lastSuccessStack = null;

            Self = car.Clone();

            if (_lastCall == LastSuccess)
                LastSuccess = _lastCall;

            for (var t = 0; t < MyStrategy.world.Tick - _lastCall && _lastSuccessStack != null && _lastSuccessStack.Count > 0; t++)
            {
                _lastSuccessStack[0].Times--;
                _lastSuccessStack.Normalize();
            }
            if (_lastSuccessStack != null && (_lastSuccessStack.Count == 0 || _useDist2 && _lastSuccessStack.ComputeTime() < 30))
                _lastSuccessStack = null;

            _lastCall = MyStrategy.world.Tick;

            /*
             * Количество бонусов на расстоянии 0.5t
             * Если изменилось - пересчитывать сильно
             */
            var bonusesCount05 = MyStrategy.Bonuses
                .Count(bonus => Self.GetDistanceTo(bonus) < Const.TileSize / 2);

            /*
             * Количество бонусов на расстоянии 2t
             * Если изменилось - чуть нужно пересчитать
             */
            var bonusesCount2 = MyStrategy.Bonuses
                .Count(
                    bonus =>
                        Self.GetDistanceTo(bonus) < Const.TileSize*2 &&
                        MyStrategy.CellDistance(Self, bonus) <= 2);

            // Если был success на прошлом тике, то продолжаем. Или каждые _interval тиков.
            if (Const.Game.InitialFreezeDurationTicks < MyStrategy.world.Tick &&
                bonusesCount05 == _bonusesCount05 &&
                LastSuccess < MyStrategy.world.Tick - 1 &&
                (MyStrategy.world.Tick - (LastSuccess + 1))%_interval != 0)
            {
                _validateLastSuccessStack();
                return _lastSuccessStack;
            }

            /*
             * Смотрим на шины, которые на расстоянии не более 6 тайлов
             */
            var prevProj = _projCandidates;
            _projCandidates = MyStrategy.Tires
                .Where(
                    proj =>
                        Self.GetDistanceTo(proj[0]) <= Const.TileSize * 6 &&
                        MyStrategy.CellDistance(Self, proj[0]) <= 6)
                .ToArray();

            var extended = MyStrategy.ExtendWaySegments(pts, 50);
            _bruteWayPoints = extended.GetRange(0, Math.Min(_waypointsCount, extended.Count)).ToArray();
            if (LastStageMove.IsUseNitro && _turnsCount(_bruteWayPoints) > 1)
                return null;
            #if DEBUG
            var bruteWayPoints = new Points();
            bruteWayPoints.AddRange(_bruteWayPoints);
            Visualizer.SegmentsDrawQueue.Add(new object[]{ Brushes.Brown, bruteWayPoints, 0.0 });
            #endif
            _needDist = Const.TileSize*0.5 - 3;
            _needDist2 = Const.TileSize - 3;
            _turnTo = _bruteWayPoints[_bruteWayPoints.Length - 1];
            _turnTo2 = _bruteWayPoints[Math.Min(_bruteWayPoints.Length - 1, (int)(_bruteWayPoints.Length * 0.83))];
            #if DEBUG
            Visualizer.CircleFillQueue.Add(new Tuple<Brush, ACircularUnit>(Brushes.OrangeRed, new ACircularUnit { X = _turnTo.X, Y = _turnTo.Y, Radius = 20}));
            Visualizer.CircleFillQueue.Add(new Tuple<Brush, ACircularUnit>(Brushes.Orange, new ACircularUnit { X = _turnTo2.X, Y = _turnTo2.Y, Radius = 20 }));
            #endif

            _patterns = Patterns.Select(pt => new PathPattern
            {
                From = pt.From,
                To = pt.To,
                Step = pt.Step,
                Move = pt.Move.Clone()
            }).ToArray();
            foreach (var p in _patterns)
            {
                if (p.Move.WheelTurn is TurnPattern)
                {
                    var turnPattern = p.Move.WheelTurn as TurnPattern;
                    if (turnPattern.Pattern == TurnPatternType.ToNext)
                        p.Move.WheelTurn = Self.GetAngleTo(_turnTo) < 0 ? -1 : 1;
                    else if (turnPattern.Pattern == TurnPatternType.FromNext)
                        p.Move.WheelTurn = Self.GetAngleTo(_turnTo) < 0 ? 1 : -1;
                }
            }

            _movesStack = new Moves();
            _bestMovesStack = new Moves();
            _bestTime = MyStrategy.Infinity;
            _bestImportance = 0;

            /*
             * Смотрим на бонусы, которые на расстоянии не более 4t
             * TODO: уменьшить приоритет бонусов, которые может быть возьмет другой (в.т.ч тиммейт)
             */
            _bonusCandidates = MyStrategy.Bonuses
                .Where(
                    bonus =>
                        MyStrategy.world.Tick > 270 && // Не смотреть на бонусы при старте!!!
                        Self.GetDistanceTo(bonus) <= Const.TileSize * 4 &&
                        MyStrategy.CellDistance(Self, bonus) <= 4
                )
                .ToArray();

            /*
             * Смотрим на лужи, которые на расстоянии не более 5 тайлов
             */
            var prevSlicks = _slickCandidates;
            _slickCandidates = MyStrategy.OilSlicks
                .Where(
                    slick =>
                        Self.GetDistanceTo(slick) <= Const.TileSize*5 &&
                        MyStrategy.CellDistance(Self, slick) <= 5
                )
                .ToArray();

            /*
             * Пытаться объехать тех, которые
             * - Крашнулись
             * - Убиты
             * - Двигатель меньше чем на 0.5 мощности
             * - Двигаются по встречной
             *
             * - Если у меня нитро, или будет нитро
             *
             * - Своих
             */
            var prevCars = _carCandidates;
            _carCandidates = MyStrategy.Others
                .Where(opp => opp[0].GetDistanceTo(Self) < Const.TileSize*9)
                .Where(
                    opp =>
                        opp[0].Original.IsTeammate ||
                        MyStrategy.IsCrashed(opp[0].Original) ||
                        !DurabilityObserver.IsActive(opp[0].Original) ||
                        opp[0].EnginePower < 0.5 ||
                        Self.RemainingNitroTicks > 0 ||
                        Math.Abs(Geom.GetAngleBetween(Self.Speed, opp[0].Speed)) > Math.PI / 2
                )
                .Where(opp => MyStrategy.CellDistance(Self, opp[0]) <= 9) // 9 - потому что он может ехать по встречке
                .ToArray();

            if (_cache != null)
            {
                for (var k = 0; k < _patterns.Length; k++)
                {
                    var range = (prevSlicks == null || prevCars == null || prevProj == null
                        || _bonusesCount2 != bonusesCount2
                        || prevSlicks.Length != _slickCandidates.Length
                        || prevCars.Length != _carCandidates.Length
                        || prevProj.Length != _projCandidates.Length)
                        ? (k == 0 ? 6 : 4)
                        : (k == 0 ? 6 : 2);

                    if (_bonusesCount05 != bonusesCount05 || Special && k == 0)
                        range = 10;

                    _patterns[k].From = Math.Max(0, _cache[k].Times - range);
                    _patterns[k].To = Math.Min(_patterns[k].To * 9 / 7, _cache[k].Times + range);
                    _patterns[k].Step = 2;
                }
            }

            _bonusesCount05 = bonusesCount05;
            _bonusesCount2 = bonusesCount2;

            var wayPointRequired = false;
            for(var i = _bruteWayPoints.Length - 1; i >= 0; i--)
            {
                if (_bruteWayPoints[i].GetDistanceTo2(_turnTo) < _needDist*_needDist)
                {
                    for (var j = 0; j < i; j++)
                        wayPointRequired |=
                            MyStrategy.GetNextWayPoint(Self.Original).Equals(MyStrategy.GetCell(_bruteWayPoints[j]));
                    break;
                }
            }

            _doRecursive(Self, 0, new PassedInfo { WayPoint = !wayPointRequired });
            _cache = null;
            if (_bestTime == MyStrategy.Infinity)
                return _lastSuccessStack;

            if (_bestMovesStack.ComputeTime() != _bestTime)
                throw new Exception("ComputeTime != BestTime");

            LastSuccess = MyStrategy.world.Tick;
            _cache = _bestMovesStack.Clone();

            if (_maxTicksInfo == null)
                _maxTicksInfo = new int[_bestMovesStack.Count];
            for (var i = 0; i < _maxTicksInfo.Length; i++)
                _maxTicksInfo[i] = Math.Max(_maxTicksInfo[i], _bestMovesStack[i].Times);

            _bestMovesStack.Normalize();
            _lastSuccessStack = _bestMovesStack.Clone();
            return _bestMovesStack;
        }
Example #33
0
 public bool _modelMove(ACar car, AMove m, PassedInfo total)
 {
     return AMove.ModelMove(car, m, total,
         _bonusCandidates, _slickCandidates, _projCandidates, _carCandidates);
 }
Example #34
0
 /*
  * Проверка что кто-то стоит впереди
  * 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)
         );
 }
Example #35
0
        private void _doRecursive(ACar model, int patternIndex, PassedInfo total)
        {
            model = model.Clone();
            total = total.Clone();

            if (patternIndex == _patterns.Length)
            {
                var m = LastStageMove.Clone();
                m.WheelTurn = _turnTo.Clone();

                if (m.IsUseNitro && (model.Speed.Length > 22 || m.EnginePower < 0))
                    return;

                var penalty = 0.0;

                for (var i = 0; ; i++)
                {
                    if (i == 200 && m.EnginePower >= 0 || i == 250 && m.EnginePower < 0)
                        return;

                    var dst = _turnTo.GetDistanceTo2(model);
                    if (dst < _needDist*_needDist)
                        break;

                    if (!_modelMove(model, m, total))
                    {
                        if (_useDist2 && m.EnginePower <= 1 && !LastStageMove.IsUseNitro)
                        {
                            if (dst < _needDist2 * _needDist2)
                            {
                                penalty = MagicConst.SecondDistDangerCoeff;
                                total.Importance -= penalty;
                                m.Times++;
                                break;
                            }
                        }
                        return;
                    }

                    m.Times++;
                }
                if (!total.WayPoint)
                    return;
                if (!MyStrategy.CheckVisibility(Self.Original, model, penalty > 0 ? _turnTo2 : _turnTo, 20))
                    return;

                if (model.EnginePower < 0)
                {
                    penalty += MagicConst.BackMoveDangerCoeff;
                    total.Importance -= MagicConst.BackMoveDangerCoeff;
                }

                if (total.Time - total.Importance < _bestTime - _bestImportance)
                {
                    _bestTime = total.Time;
                    _bestImportance = total.Importance;
                    _bestMovesStack = _movesStack.Clone();
                    _bestMovesStack.Add(m);
                    _bestMovesStack.Penalty = penalty;
                }
                return;
            }

            var pattern = _patterns[patternIndex];

            _carMoveFunc(model, pattern.From, pattern.To, pattern.Step,
                pattern.Move.Clone(), total, (aCar, passed) =>
                {
                    // ReSharper disable once ConvertToLambdaExpression
                    _doRecursive(aCar.Clone(), patternIndex + 1, passed.Clone());
                });
        }
Example #36
0
File: ACar.cs Project: znsoft/AiCup
 public bool IntersectWith(ACar car, double safeMargin)
 {
     if (GetDistanceTo2(car) > Geom.Sqr(Const.CarDiagonalHalfLength + Const.CarDiagonalHalfLength))
         return false;
     return Geom.PolygonsIntersect(GetRect(0), car.GetRect(safeMargin));
 }
Example #37
0
        private void _doRecursive(ACar model, int patternIndex, PassedInfo total)
        {
            model = model.Clone();
            total = total.Clone();

            if (patternIndex == _patterns.Length)
            {
                var m = LastStageMove.Clone();
                m.WheelTurn = _turnTo.Clone();

                if (m.IsUseNitro && (model.Speed.Length > 22 || m.EnginePower < 0))
                {
                    return;
                }

                var penalty = 0.0;

                for (var i = 0; ; i++)
                {
                    if (i == 200 && m.EnginePower >= 0 || i == 250 && m.EnginePower < 0)
                    {
                        return;
                    }

                    var dst = _turnTo.GetDistanceTo2(model);
                    if (dst < _needDist * _needDist)
                    {
                        break;
                    }

                    if (!_modelMove(model, m, total))
                    {
                        if (_useDist2 && m.EnginePower <= 1 && !LastStageMove.IsUseNitro)
                        {
                            if (dst < _needDist2 * _needDist2)
                            {
                                penalty           = MagicConst.SecondDistDangerCoeff;
                                total.Importance -= penalty;
                                m.Times++;
                                break;
                            }
                        }
                        return;
                    }

                    m.Times++;
                }
                if (!total.WayPoint)
                {
                    return;
                }
                if (!MyStrategy.CheckVisibility(Self.Original, model, penalty > 0 ? _turnTo2 : _turnTo, 20))
                {
                    return;
                }

                if (model.EnginePower < 0)
                {
                    penalty          += MagicConst.BackMoveDangerCoeff;
                    total.Importance -= MagicConst.BackMoveDangerCoeff;
                }

                if (total.Time - total.Importance < _bestTime - _bestImportance)
                {
                    _bestTime       = total.Time;
                    _bestImportance = total.Importance;
                    _bestMovesStack = _movesStack.Clone();
                    _bestMovesStack.Add(m);
                    _bestMovesStack.Penalty = penalty;
                }
                return;
            }

            var pattern = _patterns[patternIndex];

            _carMoveFunc(model, pattern.From, pattern.To, pattern.Step,
                         pattern.Move.Clone(), total, (aCar, passed) =>
            {
                // ReSharper disable once ConvertToLambdaExpression
                _doRecursive(aCar.Clone(), patternIndex + 1, passed.Clone());
            });
        }
Example #38
0
        bool CheckBackMove(Point turnCenter)
        {
            const int ticksToCheck = 40;

            for (var power = -1; power <= 1; power += 2)
            {
                if (BackModeRemainTicks == 0 && PositionsHistory.Count > ticksToCheck)
                {
                    if (
                        PositionsHistory[PositionsHistory.Count - 1].GetDistanceTo(
                            PositionsHistory[PositionsHistory.Count - ticksToCheck]) < 20)
                    {
                        var model = new ACar(self) {EnginePower = -power};
                        var cnt = 0;
                        for (var i = 0; i < 80; i++)
                            if (ModelMove(model, new AMove {EnginePower = -power, IsBrake = false, WheelTurn = 0},
                                simpleMode: false, exactlyBorders: true))
                                cnt++;
                        if (cnt < 25 || IsSomeoneAhead(new ACar(self), -power))
                        {
                            BackModeRemainTicks = 50;
                            BackModeTurn = self.GetAngleTo(turnCenter.X, turnCenter.Y) < 0 ? -power : power;
                            BackModePower = power;
                            break;
                        }
                    }
                }
            }
            if (BackModeRemainTicks > 0)
            {
                BackModeRemainTicks--;
                move.EnginePower = BackModePower;
                move.WheelTurn = BackModeTurn;
                return true;
            }
            return false;
        }
Example #39
0
        public Moves Do(ACar car, Points pts)
        {
            // Проверка что данный путь был выбран
            if (_selectThisTick + 1 != MyStrategy.world.Tick)
            {
                _lastSuccessStack = null;
            }

            Self = car.Clone();

            if (_lastCall == LastSuccess)
            {
                LastSuccess = _lastCall;
            }

            for (var t = 0; t < MyStrategy.world.Tick - _lastCall && _lastSuccessStack != null && _lastSuccessStack.Count > 0; t++)
            {
                _lastSuccessStack[0].Times--;
                _lastSuccessStack.Normalize();
            }
            if (_lastSuccessStack != null && (_lastSuccessStack.Count == 0 || _useDist2 && _lastSuccessStack.ComputeTime() < 30))
            {
                _lastSuccessStack = null;
            }

            _lastCall = MyStrategy.world.Tick;

            /*
             * Количество бонусов на расстоянии 0.5t
             * Если изменилось - пересчитывать сильно
             */
            var bonusesCount05 = MyStrategy.Bonuses
                                 .Count(bonus => Self.GetDistanceTo(bonus) < Const.TileSize / 2);

            /*
             * Количество бонусов на расстоянии 2t
             * Если изменилось - чуть нужно пересчитать
             */
            var bonusesCount2 = MyStrategy.Bonuses
                                .Count(
                bonus =>
                Self.GetDistanceTo(bonus) < Const.TileSize * 2 &&
                MyStrategy.CellDistance(Self, bonus) <= 2);

            // Если был success на прошлом тике, то продолжаем. Или каждые _interval тиков.
            if (Const.Game.InitialFreezeDurationTicks < MyStrategy.world.Tick &&
                bonusesCount05 == _bonusesCount05 &&
                LastSuccess < MyStrategy.world.Tick - 1 &&
                (MyStrategy.world.Tick - (LastSuccess + 1)) % _interval != 0)
            {
                _validateLastSuccessStack();
                return(_lastSuccessStack);
            }

            /*
             * Смотрим на шины, которые на расстоянии не более 6 тайлов
             */
            var prevProj = _projCandidates;

            _projCandidates = MyStrategy.Tires
                              .Where(
                proj =>
                Self.GetDistanceTo(proj[0]) <= Const.TileSize * 6 &&
                MyStrategy.CellDistance(Self, proj[0]) <= 6)
                              .ToArray();

            var extended = MyStrategy.ExtendWaySegments(pts, 50);

            _bruteWayPoints = extended.GetRange(0, Math.Min(_waypointsCount, extended.Count)).ToArray();
            if (LastStageMove.IsUseNitro && _turnsCount(_bruteWayPoints) > 1)
            {
                return(null);
            }
#if DEBUG
            var bruteWayPoints = new Points();
            bruteWayPoints.AddRange(_bruteWayPoints);
            Visualizer.SegmentsDrawQueue.Add(new object[] { Brushes.Brown, bruteWayPoints, 0.0 });
#endif
            _needDist  = Const.TileSize * 0.5 - 3;
            _needDist2 = Const.TileSize - 3;
            _turnTo    = _bruteWayPoints[_bruteWayPoints.Length - 1];
            _turnTo2   = _bruteWayPoints[Math.Min(_bruteWayPoints.Length - 1, (int)(_bruteWayPoints.Length * 0.83))];
#if DEBUG
            Visualizer.CircleFillQueue.Add(new Tuple <Brush, ACircularUnit>(Brushes.OrangeRed, new ACircularUnit {
                X = _turnTo.X, Y = _turnTo.Y, Radius = 20
            }));
            Visualizer.CircleFillQueue.Add(new Tuple <Brush, ACircularUnit>(Brushes.Orange, new ACircularUnit {
                X = _turnTo2.X, Y = _turnTo2.Y, Radius = 20
            }));
#endif

            _patterns = Patterns.Select(pt => new PathPattern
            {
                From = pt.From,
                To   = pt.To,
                Step = pt.Step,
                Move = pt.Move.Clone()
            }).ToArray();
            foreach (var p in _patterns)
            {
                if (p.Move.WheelTurn is TurnPattern)
                {
                    var turnPattern = p.Move.WheelTurn as TurnPattern;
                    if (turnPattern.Pattern == TurnPatternType.ToNext)
                    {
                        p.Move.WheelTurn = Self.GetAngleTo(_turnTo) < 0 ? -1 : 1;
                    }
                    else if (turnPattern.Pattern == TurnPatternType.FromNext)
                    {
                        p.Move.WheelTurn = Self.GetAngleTo(_turnTo) < 0 ? 1 : -1;
                    }
                }
            }

            _movesStack     = new Moves();
            _bestMovesStack = new Moves();
            _bestTime       = MyStrategy.Infinity;
            _bestImportance = 0;

            /*
             * Смотрим на бонусы, которые на расстоянии не более 4t
             * TODO: уменьшить приоритет бонусов, которые может быть возьмет другой (в.т.ч тиммейт)
             */
            _bonusCandidates = MyStrategy.Bonuses
                               .Where(
                bonus =>
                MyStrategy.world.Tick > 270 &&         // Не смотреть на бонусы при старте!!!
                Self.GetDistanceTo(bonus) <= Const.TileSize * 4 &&
                MyStrategy.CellDistance(Self, bonus) <= 4
                )
                               .ToArray();


            /*
             * Смотрим на лужи, которые на расстоянии не более 5 тайлов
             */
            var prevSlicks = _slickCandidates;
            _slickCandidates = MyStrategy.OilSlicks
                               .Where(
                slick =>
                Self.GetDistanceTo(slick) <= Const.TileSize * 5 &&
                MyStrategy.CellDistance(Self, slick) <= 5
                )
                               .ToArray();

            /*
             * Пытаться объехать тех, которые
             * - Крашнулись
             * - Убиты
             * - Двигатель меньше чем на 0.5 мощности
             * - Двигаются по встречной
             *
             * - Если у меня нитро, или будет нитро
             *
             * - Своих
             */
            var prevCars = _carCandidates;
            _carCandidates = MyStrategy.Others
                             .Where(opp => opp[0].GetDistanceTo(Self) < Const.TileSize * 9)
                             .Where(
                opp =>
                opp[0].Original.IsTeammate ||
                MyStrategy.IsCrashed(opp[0].Original) ||
                !DurabilityObserver.IsActive(opp[0].Original) ||
                opp[0].EnginePower < 0.5 ||
                Self.RemainingNitroTicks > 0 ||
                Math.Abs(Geom.GetAngleBetween(Self.Speed, opp[0].Speed)) > Math.PI / 2
                )
                             .Where(opp => MyStrategy.CellDistance(Self, opp[0]) <= 9) // 9 - потому что он может ехать по встречке
                             .ToArray();


            if (_cache != null)
            {
                for (var k = 0; k < _patterns.Length; k++)
                {
                    var range = (prevSlicks == null || prevCars == null || prevProj == null ||
                                 _bonusesCount2 != bonusesCount2 ||
                                 prevSlicks.Length != _slickCandidates.Length ||
                                 prevCars.Length != _carCandidates.Length ||
                                 prevProj.Length != _projCandidates.Length)
                        ? (k == 0 ? 6 : 4)
                        : (k == 0 ? 6 : 2);

                    if (_bonusesCount05 != bonusesCount05 || Special && k == 0)
                    {
                        range = 10;
                    }

                    _patterns[k].From = Math.Max(0, _cache[k].Times - range);
                    _patterns[k].To   = Math.Min(_patterns[k].To * 9 / 7, _cache[k].Times + range);
                    _patterns[k].Step = 2;
                }
            }

            _bonusesCount05 = bonusesCount05;
            _bonusesCount2  = bonusesCount2;

            var wayPointRequired = false;
            for (var i = _bruteWayPoints.Length - 1; i >= 0; i--)
            {
                if (_bruteWayPoints[i].GetDistanceTo2(_turnTo) < _needDist * _needDist)
                {
                    for (var j = 0; j < i; j++)
                    {
                        wayPointRequired |=
                            MyStrategy.GetNextWayPoint(Self.Original).Equals(MyStrategy.GetCell(_bruteWayPoints[j]));
                    }
                    break;
                }
            }

            _doRecursive(Self, 0, new PassedInfo {
                WayPoint = !wayPointRequired
            });
            _cache = null;
            if (_bestTime == MyStrategy.Infinity)
            {
                return(_lastSuccessStack);
            }

            if (_bestMovesStack.ComputeTime() != _bestTime)
            {
                throw new Exception("ComputeTime != BestTime");
            }

            LastSuccess = MyStrategy.world.Tick;
            _cache      = _bestMovesStack.Clone();

            if (_maxTicksInfo == null)
            {
                _maxTicksInfo = new int[_bestMovesStack.Count];
            }
            for (var i = 0; i < _maxTicksInfo.Length; i++)
            {
                _maxTicksInfo[i] = Math.Max(_maxTicksInfo[i], _bestMovesStack[i].Times);
            }

            _bestMovesStack.Normalize();
            _lastSuccessStack = _bestMovesStack.Clone();
            return(_bestMovesStack);
        }
Example #40
0
        void AlternativeMove(Points pts)
        {
            var car = new ACar(self);

            var backBruteRes = _doAndSelectBrute(BackBrutes, pts);

            if (backBruteRes.Item1 != -1)
            {
                BackBrutes[backBruteRes.Item1].SelectThis();
                var mv = backBruteRes.Item2[backBruteRes.Item1];
                if (mv.Count > 0)
                {
                    mv[0].Apply(move, new ACar(self));
                    ComputedPath[self.Id] = GetCarPath(self, mv);
            #if DEBUG
                    Visualizer.DrawWays(self, backBruteRes.Item2, backBruteRes.Item1);
            #endif
                    return;
                }
            }

            // change points
            pts = GetAlternativeWaySegments(self);
            var turnCenter = pts[1];

            var tmp = new ACar(self);
            var aa = tmp + tmp.Speed;
            if (Math.Abs(tmp.GetAngleTo(aa)) > Math.PI / 2)
            {
                move.EnginePower = 1;
                move.WheelTurn *= -1;
                return;
            }

            move.EnginePower = 1.0;

            if (car.GetDistanceTo(turnCenter) < 1.6 * Const.TileSize)
            {
                move.EnginePower = 0.8;
            }

            if (car.GetDistanceTo(turnCenter) < 1.0 * Const.TileSize)
            {
                if (GetSpeed(self) > 11)
                    move.IsBrake = true;
            }
            move.WheelTurn = car.GetAngleTo(turnCenter);

            if (BAD_TESTING_STRATEGY)
            {
                if (turnCenter.GetDistanceTo(self) >= 7*Const.TileSize &&
                    Math.Abs(car.GetAngleTo(turnCenter)) < Math.PI/6)
                {
                    move.IsUseNitro = true;
                }
            }
        }
Example #41
0
 public bool _modelMove(ACar car, AMove m, PassedInfo total)
 {
     return(AMove.ModelMove(car, m, total,
                            _bonusCandidates, _slickCandidates, _projCandidates, _carCandidates));
 }
Example #42
0
        public static bool ModelMove(ACar car, AMove m, PassedInfo total,
                                     ABonus[] bonusCandidates, AOilSlick[] slickCandidates, AProjectile[][] projCandidates, ACar[][] carCandidates)
        {
            double prevStateX = 0, prevStateY = 0, prevStateAngle = 0;

            if (m.RangesMode)
            {
                prevStateX     = car.X;
                prevStateY     = car.Y;
                prevStateAngle = car.Angle;
            }

            var turn = m.WheelTurn is Point?MyStrategy.TurnRound(car.GetAngleTo(m.WheelTurn as Point)) : Convert.ToDouble(m.WheelTurn);

            var isBreak = m.IsBrake;

            // если сдаю назад но кочусь вперед
            if (m.EnginePower < 0 && car.EnginePower > 0)
            {
                isBreak = true;
            }
            // если еду вперед но кочусь назад
            else if (car.EnginePower < 0 && m.EnginePower > 0)
            {
                turn   *= -1;
                isBreak = true;
            }

            var simpleMode = total.Time > 41;
            var checking   = !simpleMode || (MyStrategy.world.Tick + total.Time) % 4 == 0;

            car.Move(m.EnginePower, turn, isBreak, m.IsUseNitro, simpleMode);

            if (checking)
            {
                for (var i = 0; i < bonusCandidates.Length; i++)
                {
                    if (total.Bonuses[i]) // бонус уже взят
                    {
                        continue;
                    }

                    var bonus = bonusCandidates[i];
                    if (car.TakeBonus(bonus))
                    {
                        total.Importance += bonus.GetImportance(car.Original) * MagicConst.BonusImportanceCoeff;
                        total.Bonuses[i]  = true;
                    }
                }

                if (!total.Slicks) // если не въехал ни в одну лужу
                {
                    foreach (var slick in slickCandidates)
                    {
                        if (total.Slicks)
                        {
                            break;
                        }
                        slick.RemainingLifetime -= total.Time;
                        if (slick.Intersect(car, 9))
                        {
                            total.Importance -= slick.GetDanger() * MagicConst.OilSlickDangerCoeff *
                                                (car.RemainingNitroTicks > 0 ? 2 : 1);
                            total.Slicks = true;
                        }
                        slick.RemainingLifetime += total.Time;
                    }
                }
                if (projCandidates.Length > 0 && total.Time < projCandidates[0].Length)
                {
                    for (var i = 0; i < projCandidates.Length; i++)
                    {
                        if (total.Projectiles[i])
                        {
                            continue;
                        }

                        var proj = projCandidates[i][total.Time];

                        if (proj.Intersect(car, 5))
                        {
                            total.Importance    -= proj.GetDanger() * MagicConst.TireDangerCoeff;
                            total.Projectiles[i] = true;
                        }
                    }
                }
                if (!total.Cars)
                {
                    for (var i = 0; i < carCandidates.Length; i++)
                    {
                        if (total.Time >= carCandidates[i].Length)
                        {
                            continue;
                        }

                        var opp = carCandidates[i][total.Time];

                        if (car.IntersectWith(opp, opp.Original.IsTeammate ? 20 : 0))
                        {
                            if ((car.Speed.Length > 8 || car.Original.IsTeammate) && MyStrategy.world.Tick > 400)
                            {
                                // чтобы не боялся протаранить на маленькой скорости
                                total.Importance -= car.RemainingNitroTicks > 0
                                    ? MagicConst.InactiveCarNitroDangerCoeff
                                    : MagicConst.InactiveCarDangerCoeff;
                            }
                            total.Cars = true;
                            break;
                        }
                    }
                }
            }

            total.Time++;

            var res = true;

            if (checking)
            {
                // проверка на стены
                res = car.GetRectEx().All(p => !MyStrategy.IntersectTail(p, m.SafeMargin));

                // проверка что можно проехать точно возле стены
                if (!res && car.RemainingNitroTicks == 0 && m.ExactlyMargin < m.SafeMargin &&
                    car.GetRectEx().All(p => !MyStrategy.IntersectTail(p, m.ExactlyMargin)))
                {
                    if (!total.ExactlyBorder)
                    {
                        total.Importance -= MagicConst.ExactlyBorderDangerCoeff;
                    }
                    total.ExactlyBorder = true;
                    res = true;
                }

                // проверка что можно проскользнуть по стене
                if (!m.RangesMode && !res && car.RemainingNitroTicks == 0 && m.ExtraMargin < m.ExactlyMargin &&
                    car.GetRectEx().All(p => !MyStrategy.IntersectTail(p, total.Time < 20 ? -2 : m.ExtraMargin)))
                {
                    if (!total.OutOfBoreder)
                    {
                        total.Importance  -= MagicConst.OutOfBorederDangerCoeff;
                        total.OutOfBoreder = true;
                    }
                    res = true;
                }

                if (!total.WayPoint)
                {
                    total.WayPoint = MyStrategy.GetNextWayPoint(car.Original).Equals(MyStrategy.GetCell(car));
                }

                if (!res && m.RangesMode)
                {
                    res = true;

                    // HACK
                    car.X            = prevStateX;
                    car.Y            = prevStateY;
                    car.Angle        = prevStateAngle;
                    car.Speed        = Point.Zero;
                    car.AngularSpeed = 0;
                }
            }
            return(res);
        }