Esempio n. 1
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);
        }