예제 #1
0
        private double AngelToWayPoint(Car self, World world, Game game, Move move)
        {
            double nextWaypointX = (self.NextWaypointX + 0.5D) * game.TrackTileSize;
            double nextWaypointY = (self.NextWaypointY + 0.5D) * game.TrackTileSize;
            double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY);

            double max = .32D;
            double delta = speedModule / MaxSpeed;
            double cornerTileOffset = max * delta * game.TrackTileSize;

            switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY])
            {
                case TileType.LeftTopCorner:
                    nextWaypointX += cornerTileOffset;
                    nextWaypointY += cornerTileOffset;
                    break;
                case TileType.RightTopCorner:
                    nextWaypointX -= cornerTileOffset;
                    nextWaypointY += cornerTileOffset;
                    break;
                case TileType.LeftBottomCorner:
                    nextWaypointX += cornerTileOffset;
                    nextWaypointY -= cornerTileOffset;
                    break;
                case TileType.RightBottomCorner:
                    nextWaypointX -= cornerTileOffset;
                    nextWaypointY -= cornerTileOffset;
                    break;
            }

            return self.GetAngleTo(nextWaypointX, nextWaypointY);
        }
        public PlayerContext(Car[] cars, World world)
        {
            this.cars = new Car[cars.Length];
            Array.Copy(cars, this.cars, cars.Length);

            this.world = world;
        }
예제 #3
0
        public void Move(Car self, World world, Game game, Move move)
        {
            move.EnginePower = 1.0D;
            move.IsThrowProjectile = true;
            move.IsSpillOil = true;

            if (world.Tick > game.InitialFreezeDurationTicks) {
                move.IsUseNitro = true;
            }
        }
예제 #4
0
        public void Move(Car self, World world, Game game, Move move)
        {
            double nextWaypointX = (self.NextWaypointX + 0.5) * game.TrackTileSize;
            double nextWaypointY = (self.NextWaypointY + 0.5) * game.TrackTileSize;

            Console.WriteLine (self.NextWaypointX + " " + self.NextWaypointY);

            double cornerTileOffset = 0.25D * game.TrackTileSize;

            switch (world.TilesXY [self.NextWaypointX] [self.NextWaypointY]) {
            case TileType.LeftTopCorner:
                nextWaypointX += cornerTileOffset;
                nextWaypointY += cornerTileOffset;
                break;
            case TileType.RightTopCorner:
                nextWaypointX -= cornerTileOffset;
                nextWaypointY += cornerTileOffset;
                break;
            case TileType.LeftBottomCorner:
                nextWaypointX += cornerTileOffset;
                nextWaypointY -= cornerTileOffset;
                break;
            case TileType.RightBottomCorner:
                nextWaypointX -= cornerTileOffset;
                nextWaypointY -= cornerTileOffset;
                break;

            }

            double angleToWaypoint = self.GetAngleTo (nextWaypointX, nextWaypointY);
            double speedModule = hypot (self.SpeedX, self.SpeedY);

            move.WheelTurn = (angleToWaypoint * 32.0D / System.Math.PI);
            move.EnginePower = (1.0D);
            if (speedModule > 30)
                move.EnginePower = 0;

            if (speedModule * speedModule * System.Math.Abs (angleToWaypoint)
                > 2.5D * 2.5D * System.Math.PI) {

                move.EnginePower = (0.0D);
                if (speedModule > 10) {
                    move.IsBrake = true;
                    if (angleToWaypoint > 0)
                        move.WheelTurn = 1;
                    else
                        move.WheelTurn = -1;
                }
            }

            move.IsThrowProjectile = true;
            move.IsSpillOil = true;
        }
예제 #5
0
        public void Move(Car self, World world, Game game, Move move)
        {
            double nextWaypointX = (self.NextWaypointX + 0.5D) * game.TrackTileSize;
            double nextWaypointY = (self.NextWaypointY + 0.5D) * game.TrackTileSize;

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

            if (backNumber < maxBackNumber)
            {
                backNumber++;
                move.WheelTurn = -oldAngle;
                move.EnginePower = -1;
                number = -100;
                return;
            }
            double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY);
            if (Math.Abs(speedModule) < .05)
                number++;
            else
                number = 0;
            if (number > maxNumber)
            {
                backNumber = 0;
                number = 0;
                oldAngle = angleToWaypoint * 32.0D / Math.PI;
            }

            move.EnginePower = 1;
            if (Math.Abs(nextWaypointX - self.X) < 1600 && Math.Abs(nextWaypointY - self.Y) < 1600)
            {
                angleToWaypoint = AngelToWayPoint(self, world, game, move);
                move.IsBrake = IsUseBreak(self, world, game, move);
            }
            move.WheelTurn = angleToWaypoint * 32.0D / Math.PI;
            Console.WriteLine(String.Format("{0} - {1}", self.SpeedX, self.SpeedY));

            move.IsUseNitro = IsUseNitro(self, world, game, move);
            move.IsThrowProjectile = IsThrow(self, world, game, move);
            move.IsSpillOil = IsSpillOil(self, world, game, move);

            veryOldTileType = oldTileType;
            oldTileType = world.TilesXY[self.NextWaypointX][self.NextWaypointY];
            Console.WriteLine(speedModule);
        }
예제 #6
0
        public void Move(Car self, World world, Game game, Move move)
        {
            Debug.beginPost();
            Constants.setConstants(game, world);
            currentTick = world.Tick;

            if (map == null) {
                waypoints = world.Waypoints;
                map = new RoadMap(world.Width, world.Height);
                map.updateMap(world.TilesXY);
            }

            if (currentVehicle == null) {
                currentVehicle = new ManagedVehicle();
            }

            currentVehicle.setCar(self);

            currentVehicle.tick(move);

            Debug.endPost();
        }
예제 #7
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);

                        }
                    }
                }
            }
        }
예제 #8
0
파일: MyStrategy.cs 프로젝트: znsoft/AiCup
        public void Move(Car self, World world, Game game, Move move)
        {
            TimerStart();
            MyStrategy.world = world;
            Const.Game = game;
            this.move = move;
            this.self = self;
            Initialize();

            #if DEBUG
            while (Visualizer.Pause)
            {
                // pause here
            }
            Visualizer.CreateForm(world.Cars.Count(x => x.IsTeammate));
            #endif
            if (!self.IsFinishedTrack)
            {
                All = null;
                MyTeam = null;

                _move();

                if (OpponentsCars != null)
                {
                    var myTeam = new List<ACar[]>();
                    if (!ComputedPath.ContainsKey(self.Id))
                        ComputedPath[self.Id] = new int[MagicConst.OpponentsTicksPrediction].Select(x => new ACar(self)).ToArray();
                    myTeam.Add(ComputedPath[self.Id]);
                    if (TeammateCar != null)
                        myTeam.Add(TeammateCar);
                    MyTeam = myTeam.ToArray();

                    All = MyTeam.Concat(OpponentsCars).ToArray();

                    TimerStart();
                    if (CheckUseProjectile())
                        move.IsThrowProjectile = true;
                    if (CheckUseOil())
                        move.IsSpillOil = true;

                    TimerEndLog("CheckUseProjectile", 2);
                }
            }
            else if (_finishTime == Infinity)
                _finishTime = world.Tick;
            if (_finishTime < Infinity)
                Log(_finishTime);

            #if DEBUG
            if (move.IsBrake)
                Visualizer.CircleFillQueue.Add(new Tuple<Brush, ACircularUnit>(Brushes.Red,
                    new ACircularUnit {X = self.X, Y = self.Y, Radius = 30}));

            TimerEndLog("All");

            if (Brutes != null)
            {
                for (var i = 0; i < Brutes.Length; i++)
                {
                    var info = Brutes[i].GetMaxTicksInfo();
                    if (info == null)
                        continue;
                    Console.Write(i + ": ");
                    foreach (var a in info)
                        Console.Write(" " + a);
                    Console.WriteLine("(" + Brutes[i].SelectedCount + ")");
                }
            }
            Console.WriteLine();
            Visualizer.Draw();
            Thread.Sleep(12);
            #endif
        }
예제 #9
0
        private bool IsUseNitro(Car self, World world, Game game, Move move)
        {
            int currentTileX = (int)(self.X / game.TrackTileSize);
            int currentTileY = (int)(self.Y / game.TrackTileSize);

            switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY])
            {
                case TileType.LeftBottomCorner:
                case TileType.LeftTopCorner:
                case TileType.RightBottomCorner:
                case TileType.RightTopCorner:
                    return false;
            }

            switch (world.TilesXY[currentTileX][currentTileY])
            {
                case TileType.Crossroads:
                case TileType.Horizontal:
                case TileType.Vertical:
                    return true;
                default:
                    return false;
            }
        }
예제 #10
0
        private bool IsUseBreak(Car self, World world, Game game, Move move)
        {
            double speedModule = Math.Sqrt(self.SpeedX * self.SpeedX + self.SpeedY * self.SpeedY);

            switch (world.TilesXY[self.NextWaypointX][self.NextWaypointY])
            {
                case TileType.LeftBottomCorner:
                case TileType.LeftTopCorner:
                case TileType.RightBottomCorner:
                case TileType.RightTopCorner:
                    if (speedModule > MaxSpeed)
                    {
                        move.EnginePower = .8d;
                        return true;
                    }
                    break;
                default:
                    return false;
            }
            return false;
        }
예제 #11
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;
        }
예제 #12
0
        private bool IsSpillOil(Car self, World world, Game game, Move move)
        {
            int currentTileX = (int)(self.X / game.TrackTileSize);
            int currentTileY = (int)(self.Y / game.TrackTileSize);

            switch (world.TilesXY[currentTileX][currentTileY])
            {
                case TileType.LeftBottomCorner:
                case TileType.LeftTopCorner:
                case TileType.RightBottomCorner:
                case TileType.RightTopCorner:
                    return true;
                default:
                    return false;
            }
        }
예제 #13
0
 public static void setConstants(Game _game, World _world)
 {
     game = _game;
     world = _world;
 }
예제 #14
0
        public void Move(Car self, World world, Game game, Move move) {
			lastX1 = lastX2;
			lastX2 = lastX3;
			lastX3 = Math.Round(self.X, 2);
			lastY1 = lastY2;
			lastY2 = lastY3;
			lastY3 = Math.Round(self.Y, 2);

			this._game = game;
			this._move = move;
			this._self = self;
			this._world = world;

			if (rearMove) {
				move.EnginePower = -1.0D;
				move.WheelTurn = 0;//(activeTicks > 50) ? -1 : 0;
			}

			if (activeTicks == 90 && Math.Abs (lastX1 - lastX3) < 0.05 && Math.Abs (lastY1 - lastY3) < 0.05 && _world.Tick > _game.InitialFreezeDurationTicks)
				rearMove = false;

			if (activeTicks > 0) {
				activeTicks --;
				return;
			}

            if (noStuck > 0)
                noStuck--;

            if (slowDown > 0) {
				move.EnginePower = 0.5D;
			}
			else
				move.EnginePower = 1.0D;

            if (noIgnite > 0)
            {
                noIgnite--;
                //return;
            }

            move.IsThrowProjectile = false;
			move.IsSpillOil = false;

			if (world.Tick > game.InitialFreezeDurationTicks && world.Tick < game.InitialFreezeDurationTicks + 10) {
				move.WheelTurn = -15;
			}

			if (world.Tick > game.InitialFreezeDurationTicks && world.Tick < game.InitialFreezeDurationTicks + 20) {
                //				move.IsSpillOil = true;
                //				move.WheelTurn = 0;
                sDirection = world.StartingDirection;
			}

			if (world.Tick > game.InitialFreezeDurationTicks && world.Tick < game.InitialFreezeDurationTicks + 10 && move.WheelTurn == 0) {
//				move.WheelTurn = 1;
			}

            if (world.Tick > game.InitialFreezeDurationTicks + 30) {
                move.IsUseNitro = (noIgnite == 0);
                CheckTurn();
				NewTurnWheel ();
				CheckStuck ();
                if (Math.Abs(_move.WheelTurn) > Math.PI / 6)
                    move.IsUseNitro = false;
            }

			if (_thisTile != TileType.Empty) {
//				saveDirection = sDirection;
			}
        }
예제 #15
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;
        }
예제 #16
0
        public SimulatedPosition Simulate(int ticks, int step, Car self, World world, Game game, SimulatedControl control)
        {
            SimulatedPosition pos = new SimulatedPosition(self, game);

            this.game = game;

            for (int t = 0; t < ticks; t += step)
            {
                for (int a = 0; a < 10; a++)
                {
                    //pos.enginePower = AgjustPower(pos.enginePower, control.enginePower, 0.1);
                    pos.Update(0.1);
                }

            }

            return pos;
        }