Exemplo n.º 1
0
        private bool IsThrow(Car self, World world, Game game, Move move)
        {
            int maxShootDistance = 1000;
            if (self.ProjectileCount <= 0)
            {
                return false;
            }

            foreach (Car c in world.Cars)
            {
                if (c.IsTeammate)
                {
                    continue;
                }

                double enemyCarAngel = self.GetAngleTo(c.X, c.Y);
                Console.WriteLine(self.GetDistanceTo(c));
                if (self.GetDistanceTo(c) > maxShootDistance)
                {
                    continue;
                }

                if (Math.Abs(enemyCarAngel) < 0.1)
                {
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 2
0
        public void Move(Car self, World world, Game game, Move move)
        {
            if (stop)
                return;

            if (world.Tick == 0)
            {
                startX = self.X;
                startY = self.Y;
                prevX = self.X;
                prevY = self.Y;
            }

            move.EnginePower = 0;

            if (world.Tick > game.InitialFreezeDurationTicks)
            {

                double nextWaypointX = (self.NextWaypointX + 0.5D) * game.TrackTileSize;
                double nextWaypointY = (self.NextWaypointY + 0.5D) * game.TrackTileSize;

                double angleToWaypoint = self.GetAngleTo(nextWaypointX, nextWaypointY);
                double distToWaypoint = self.GetDistanceTo(nextWaypointX, nextWaypointY);

                double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY);

                travelled += self.GetDistanceTo(prevX, prevY);
                travelled2 += self.GetDistanceTo(prevX, prevY);

                prevX = self.X;
                prevY = self.Y;

                move.EnginePower = 1;

                if (travelled > 1500)
                {
                    move.EnginePower = 0;

                    if (self.EnginePower == 0)
                    {
                        if (t == -10)
                        {
                            travelled2 = 0;
                            Console.WriteLine("S: {0},{1} {2}", self.X, self.Y, self.SpeedY);
                            t = 1;
                            SimulatedControl ctrl = new SimulatedControl();

                            ctrl.enginePower = move.EnginePower;

                            pos = simulator.Simulate(t, 1, self, world, game, ctrl);
                            Console.WriteLine("P: {0},{1} {2}", pos.position.X, pos.position.Y, pos.speed.Y);
                        }
                        else if (t > 1)
                        {
                            t--;
                        }
                        else if (t == 1)
                        {
                            t--;

                            Console.WriteLine("R: {0},{1} {2}", self.X, self.Y, self.SpeedY);

                            Console.WriteLine("%: {0} / {1} ({2})", travelled2, self.GetDistanceTo(pos.position.X, pos.position.Y), 100 * self.GetDistanceTo(pos.position.X, pos.position.Y) / travelled2);

                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        public void Move(Car self, World world, Game game, Move move)
        {
            if (world.Tick == 0)
            {
                // Инициализация
                TilesXY = new TileType[world.TilesXY.Length][];
                for (int t = world.TilesXY.Length - 1; t >= 0; --t)
                {
                    TilesXY[t] = new TileType[world.TilesXY[t].Length];
                    Array.Copy(world.TilesXY[t], TilesXY[t], world.TilesXY[t].Length);
                }
            }

            // Предстартовое повышение мощности двигателя на холостых оборотах
            if (world.Tick <= game.InitialFreezeDurationTicks)
            {
                move.EnginePower = 1.0D;
                return;
            }

            // Координаты машины в таблице тайлов
            int x = (int)(self.X / game.TrackTileSize);
            int y = (int)(self.Y / game.TrackTileSize);

            // Перерасчет пути
            if (X != x || Y != y)
            {
                X = x;
                Y = y;

                int[][] LocalPathX = new int[3][];
                int[][] LocalPathY = new int[3][];

                // Путь между машиной и ближайшей путевой точкой
                FindTargets(
                    X, Y,
                    world.Waypoints[self.NextWaypointIndex][0],
                    world.Waypoints[self.NextWaypointIndex][1],
                    out LocalPathX[0], out LocalPathY[0]);

                // Путь между очередной путевой точкой и следующей путевой точкой
                for (int i = 0; i < LocalPathX.Length - 1; ++i)
                    FindTargets(
                        world.Waypoints[(self.NextWaypointIndex + i) % world.Waypoints.Length][0],
                        world.Waypoints[(self.NextWaypointIndex + i) % world.Waypoints.Length][1],
                        world.Waypoints[(self.NextWaypointIndex + i + 1) % world.Waypoints.Length][0],
                        world.Waypoints[(self.NextWaypointIndex + i + 1) % world.Waypoints.Length][1],
                        out LocalPathX[i + 1], out LocalPathY[i + 1]);

                // Путь от машины через промежуточные путевые точки к следующей путевой точке
                int Len = 0;
                for (int i = 0; i <= LocalPathX.Length - 1; ++i)
                    Len += LocalPathX[i].Length;

                PathX = new int[Len];
                PathY = new int[Len];

                Len = 0;
                for (int i = 0; i <= LocalPathX.Length - 1; ++i)
                {
                    for (int j = LocalPathX[i].Length - 1; j >= 0; --j)
                    {
                        PathX[Len + j] = LocalPathX[i][j];
                        PathY[Len + j] = LocalPathY[i][j];
                    }
                    Len += LocalPathX[i].Length;
                }

                // Срезание углов на поворотах
                correctX = 0.5;
                correctY = 0.5;
                // Определение длины прямолинейного участка пути
                n = 0;
                if (PathX[n] == X)
                {
                    int dY = PathY[n] - Y;
                    // Отрезок по вертикали
                    while (PathX[n] == X && n < PathX.Length - 1)
                        if (PathX[n + 1] == X && dY == PathY[n + 1] - PathY[n]) n++; else break;
                    // Срезание углов на поворотах
                    if (n < PathX.Length - 1)
                    {
                        if (PathX[n + 1] < PathX[n]) correctX = 0.2;
                        else correctX = 0.8;
                    }
                }
                else if (PathY[n] == Y)
                {
                    int dX = PathX[n] - X;
                    // Отрезок по горизонтали
                    while (PathY[n] == Y && n < PathY.Length - 1)
                        if (PathY[n + 1] == Y && dX == PathX[n + 1] - PathX[n]) n++; else break;
                    // Срезание углов на поворотах
                    if (n < PathX.Length - 1)
                    {
                        if (PathY[n + 1] < PathY[n]) correctY = 0.2;
                        else correctY = 0.8;
                    }
                }
            }

            // Прицельная точка - ближайший поворот
            double nextX = (PathX[n] + correctX) * game.TrackTileSize;
            double nextY = (PathY[n] + correctY) * game.TrackTileSize;

            // Расчет положения руля и педали газа - цель nextX, nextY
            double power, turn;
            GoTo(self, nextX, nextY, 0, 0, out power, out turn);
            move.EnginePower = power;
            move.WheelTurn = turn;

            // Подбор попутных бонусов
            bool bonus = false;
            foreach (Bonus b in world.Bonuses)
            {
                bool OnPath = false;
                for (int i = 0; i < n; i++)
                    if ((int)(b.X / game.TrackTileSize) == PathX[i] &&
                        (int)(b.Y / game.TrackTileSize) == PathY[i])
                        OnPath = true;

                double angle = GetAngleBetween(self.X, self.Y, b.X, b.Y, self.Angle);
                angle += GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle);

                if (Math.Abs(angle) < Math.PI / 12.0 &&
                    self.GetDistanceTo(b) < (n - 1) * game.TrackTileSize &&
                    OnPath)
                {
                    if (GetDistance(self, nextX, nextY) > GetDistance(self, b.X, b.Y))
                    {
                        nextX = b.X;
                        nextY = b.Y;
                        GoTo(self, nextX, nextY, 0, 0, out power, out turn);
                        move.EnginePower = power;
                        move.WheelTurn = turn;
                        bonus = true;
                    }
                }
            }

            // Торможение при приближении к повороту
            if (!bonus)
                if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) * 33 > self.GetDistanceTo(nextX, nextY))
                {
                    if (Math.Abs(GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle)) < Math.PI / 2 &&
                        move.EnginePower > 0)
                        move.IsBrake = true;
                    if (Math.Abs(GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle)) > Math.PI / 2 &&
                        move.EnginePower < 0)
                        move.IsBrake = true;
                    move.EnginePower = -move.EnginePower;
                }

            // Взаимодействие с соперниками
            foreach (Car c in world.Cars)
                if (!c.IsTeammate)
                {
                    if (Math.Abs(GetAngleBetween(self.X, self.Y, c.X, c.Y, self.Angle)) < Math.PI / 90.0 &&
                        self.GetDistanceTo(c) < 2400)
                        move.IsThrowProjectile = true;
                    if (Math.Abs(GetAngleBetween(self.X, self.Y, c.X, c.Y, Math.PI + self.Angle)) < Math.PI / 90.0 &&
                        self.GetDistanceTo(c) < 2400)
                        if (Math.Abs(self.AngularSpeed) > 0.005)
                            move.IsSpillOil = true;
                }

            // Если скорость меньше 1, то засекаем 60 тиков.
            // Если скорость не изменилась за это время, то 60 тиков выруливать из тупика
            // Засекаем 60 тиков перед включением режима выруливания
            if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) < 1 && TickStop == -1)
                TickStop = world.Tick;
            // Отмена режима выруливания, если скорость поднялась или вышло время работы режима
            if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) > 1 && (world.Tick - TickStop <= 60) ||
                (TickStop != -1 && world.Tick - TickStop > 160) ||
                GetDistance(self.SpeedX, self.SpeedY, 0, 0) > 10)
                TickStop = -1;
            // Режим выруливания 100 тиков
            if (TickStop != -1 && world.Tick - TickStop > 60 && world.Tick - TickStop <= 160)
            {
                GoTo(self, 2 * self.X - nextX, 2 * self.Y - nextY, 0, 0, out power, out turn);
                move.EnginePower = power;
                move.WheelTurn = turn;
            }
            if (TickStop != -1 && world.Tick - TickStop > 140 && world.Tick - TickStop <= 160)
            {
                GoTo(self, nextX, nextY, 0, 0, out power, out turn);
                move.EnginePower = power;
            }

            // Ускоряться
            if (GetDistance(self.SpeedX, self.SpeedY, 0, 0) > 1 && GetDistance(self.SpeedX, self.SpeedY, 0, 0) < 20)
                if (n > 5 && Math.Abs(GetAngleBetween(0, 0, self.SpeedX, self.SpeedY, self.Angle)) < Math.PI / 8.0D)
                    move.IsUseNitro = true;
        }