Пример #1
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            if (tilePath.Count < 4)
                return false;

            var current = MyStrategy.map.tileAt(vehicle.position);

            var currentToFirst = current.directionForTile(tilePath[0]).Value;
            var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value;
            var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value;
            var thirdToFour = tilePath[2].directionForTile(tilePath[3]).Value;

            if (!currentToFirst.isSameAxis(firstToSecond))
                return false;

            if (firstToSecond.isSameAxis(secondToThird))
                return false;

            if (firstToSecond.back() != thirdToFour)
                return false;

            var turningFrom = new Vector(currentToFirst);
            var turningTo = new Vector(firstToSecond);

            move.EnginePower = 1;
            move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, current.center, turningTo, -0.25 * Constants.tileSize));

            if (vehicle.speed.length > 15) {
                move.IsBrake = true;
            } else {
                move.IsBrake = false;
            }
            return true;
        }
Пример #2
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);
        }
Пример #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 override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            var nextTile = tilePath[0];
            //			nextTile.draw(0xFF0000);
            //			nextTile.center.draw(0xFF1010);

            if (vehicle.forward * (nextTile.center - vehicle.position) < 0.4 && vehicle.speed.length > 10) {
                move.IsBrake = true;
                move.EnginePower = -1;
            } else {
                move.IsBrake = false;
                move.EnginePower = 1;
            }

            move.WheelTurn = vehicle.forward.angleTo((nextTile.center - vehicle.position)) * 4;

            return true;
        }
Пример #6
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);
        }
Пример #7
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();
        }
Пример #8
0
        public void run()
        {
            try {
                remoteProcessClient.WriteTokenMessage(token);
                int teamSize = remoteProcessClient.ReadTeamSizeMessage();
                remoteProcessClient.WriteProtocolVersionMessage();
                Game game = remoteProcessClient.ReadGameContextMessage();

                IStrategy[] strategies = new IStrategy[teamSize];

                for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) {
                    strategies[strategyIndex] = new MyStrategy();
                }

                PlayerContext playerContext;

                while ((playerContext = remoteProcessClient.ReadPlayerContextMessage()) != null) {
                    Car[] playerCars = playerContext.Cars;
                    if (playerCars == null || playerCars.Length != teamSize) {
                        break;
                    }

                    Move[] moves = new Move[teamSize];

                    for (int carIndex = 0; carIndex < teamSize; ++carIndex) {
                        Car playerCar = playerCars[carIndex];

                        Move move = new Move();
                        moves[carIndex] = move;
                        strategies[playerCar.TeammateIndex].Move(playerCar, playerContext.World, game, move);
                    }

                    remoteProcessClient.WriteMovesMessage(moves);
                }
            } finally {
                remoteProcessClient.Close();
            }
        }
Пример #9
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            var current = MyStrategy.map.tileAt(vehicle.position);

            AxisDirection dir;

            {

                dir = current.directionForTile(tilePath[0]) ?? AxisDirection.up;

                for (int i = 1; i < 3  && i < tilePath.Count; ++i) {
                    if (tilePath[i - 1].directionForTile(tilePath[i]) != dir)
                        return false;
                }
            }

            var dirVec = new Vector(dir);

            var last = current;

            int lineTilesCtr = 0;

            foreach (var tile in tilePath) {
                if (dir.turnLeft() == last.directionForTile(tile)) {
                    var turnVector = new Vector(dir.turnLeft());
                    var dist = (vehicle.position - current.center) * turnVector + 0.15 * Constants.tileSize;
                    dirVec -= turnVector * dist / Constants.tileSize;
                    break;
                } else if (dir.turnRight() == last.directionForTile(tile)) {
                    var turnVector = new Vector(dir.turnRight());
                    var dist = (vehicle.position - current.center) * turnVector + 0.15 * Constants.tileSize;
                    dirVec -= turnVector * dist / Constants.tileSize;
                    break;
                } else if (dir != last.directionForTile(tile))
                    break;

                lineTilesCtr += 1;

                last = tile;

            }

            if (lineTilesCtr >= 8) {
                move.IsUseNitro = true;
            }

            if (vehicle.forward * dirVec > 0.3) {
                move.EnginePower = 1;
                move.WheelTurn = vehicle.steeringAngleForDirection(dirVec);
            } else {
                move.EnginePower = 0.2;
                move.WheelTurn = vehicle.steeringAngleForDirection(dirVec);
            }
            move.IsBrake = false;

            return true;
        }
Пример #10
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            if (tilePath.Count < 3)
                return false;

            var currentTile = MyStrategy.map.tileAt(vehicle.position);

            Vector turningTo;
            Vector turningFrom;

            {
                var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value;

                turningTo = new Vector(firstToSecond);

                if (firstToSecond != tilePath[1].directionForTile(tilePath[2])) {
                    return false;
                }

                var currentToFirst = currentTile.directionForTile(tilePath[0]).Value;
                if (currentToFirst.isSameAxis(firstToSecond)) {
                    return false;
                }

                turningFrom = new Vector(currentToFirst);

            }

            if (vehicle.speed.length > 10) {

                var innerSide1 = Ray.line(
                    currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5,
                    currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) + turningFrom * Constants.tileSize * 0.5
                );

                //innerSide1.draw(0x00FF00);

                var innerCircle = new Circle(currentTile.center + (turningTo + turningFrom) * Constants.tileSize * 0.5, Constants.roadMargin);

                //innerCircle.draw(0x00FF00);

                var innerCircleExtended = new Circle(innerCircle.position, innerCircle.radius + 10);

                var backWall = new Ray(tilePath[0].center  + turningFrom * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningTo * Constants.tileSize * 0.5,
                                   turningTo * Constants.tileSize * 2);

                //backWall.draw(0x00FF00);

                if (vehicle.forward * turningFrom > 0.45) {
                    var vv = new VirtualVehicle(vehicle);
                    var steering = Math.Sign(turningFrom.angleTo(turningTo));

                    for (int i = 0; i < 100; ++i) {
                        vv.simulateTick(1.0, steering);

                        if (vv.rect.isIntersect(innerSide1) || vv.rect.isIntersect(innerCircle)) {
                            move.EnginePower = 1;
                            move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, currentTile.center, turningTo, -0.15 * Constants.tileSize));
                            move.IsBrake = false;
                            return true;
                        }

                        if (vv.rect.isIntersect(backWall)) {
                            move.IsBrake = true;
                            move.EnginePower = 1;
                            move.WheelTurn = steering;
                            return true;
                        }

                        if (tilePath[1].rect.contains(vv.position)) {

                            // защита от слишком быстрого захода в поворот и ударения в заднюю стенку

                            for (int j = 0; j < 50; ++j) {

                                vv.simulateTick(1, steering);
                                if (vv.rect.isIntersect(backWall)) {
                                    move.EnginePower = 1;
                                    move.WheelTurn = steering;
                                    move.IsBrake = true;
                                    return true;
                                }

                                //vv.position.draw(0x00FF00);
                                //vv.rect.draw(0x0000FF);

                            }

                            move.EnginePower = 1;
                            move.WheelTurn = steering;
                            move.IsBrake = false;
                            return true;
                        }

                        //vv.position.draw(0xFF0000);
                        //vv.rect.draw(0x0000FF);
                    }
                } else if (vehicle.forward * turningTo > 0.5) {

                    var vv = new VirtualVehicle(vehicle);
                    var steering = Math.Sign(turningFrom.angleTo(turningTo));

                    for (int i = 0; i < 100; ++i) {
                        vv.simulateTick(1.0, 0);

                        if (vv.rect.isIntersect(innerSide1) || vv.rect.isIntersect(innerCircleExtended)) {

                            move.EnginePower = 1;
                            move.WheelTurn = -steering;
                            move.IsBrake = false;
                            return true;
                        }

                        if (tilePath[1].rect.contains(vv.position)) {
                            move.EnginePower = 1;
                            move.WheelTurn = 0;
                            move.IsBrake = false;
                            return true;
                        }

                        //vv.position.draw(0xFF0000);
                        //vv.rect.draw(0x0000FF);
                    }
                } else {
                    move.IsBrake = true;
                    move.WheelTurn = 0;
                    move.EnginePower = 1;
                    return true;
                }

            }

            move.IsBrake = false;
            move.EnginePower = 1;
            var turn = turningTo + turningFrom;
            move.WheelTurn = vehicle.steeringAngleForDirection(turn);

            return true;
        }
Пример #11
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            var forceGetBack = false;

            if (MyStrategy.currentTick > 180) {
                if (vehicle.speed.length < 1) {
                    zeroSpeedTicks += 1;
                } else {
                    zeroSpeedTicks = 0;
                }

                if (zeroSpeedTicks > 30) {
                    forceGetBack = true;
                }
            }

            if (vehicle.speed.length > 5 && !forceGetBack)
                return false;

            var target = tilePath[0].center;

            if (MyStrategy.map.intersect(vehicle.forwardRay * Constants.vehicleLength * 2) != null || forceGetBack) {
                move.IsBrake = false;
                move.EnginePower = -1;
                move.WheelTurn = -vehicle.forward.angleTo(target - vehicle.position) * 4;
                return true;
            }

            return false;
        }
Пример #12
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;
			}
        }
Пример #13
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;
            }
        }
Пример #14
0
 public abstract bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move);
Пример #15
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            if (tilePath.Count < 2)
                return false;

            var current = MyStrategy.map.tileAt(vehicle.position);

            var currentToFirst = current.directionForTile(tilePath[0]).Value;
            var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value;
            var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value;

            if (currentToFirst.isSameAxis(firstToSecond))
                return false;

            if (currentToFirst.back() != secondToThird)
                return false;

            var turningFrom = new Vector(currentToFirst);
            var turningTo = new Vector(firstToSecond);

            if (vehicle.speed.length > 10) {

                var steering = Math.Sign(turningFrom.angleTo(turningTo));

                var backWall = new Ray(
                    tilePath[0].center + turningFrom * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningTo * Constants.tileSize * 0.5,
                    turningTo * Constants.tileSize * 2
                );

                var backSideWall = new Ray(
                    backWall.p2 - turningTo * Constants.roadMargin,
                    -turningFrom * (Constants.tileSize - Constants.roadMargin)
                );

                var innerWall = new Ray(current.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5,
                                    turningFrom * Constants.tileSize);

                var innerCircle = new Circle(current.center + (new Vector(currentToFirst) + new Vector(firstToSecond)) * Constants.tileSize * 0.5, Constants.roadMargin);

                backWall.draw(0x00FF00);
                backSideWall.draw(0x00FF00);
                innerWall.draw(0x00FF00);
                innerCircle.draw(0x00FF00);

                var vv = new VirtualVehicle(vehicle);

                for (int i = 0; i < 100; ++i) {

                    vv.simulateTick(0.5, steering);

                    var rect = vv.rect;

                    if (rect.isIntersect(innerWall) || rect.isIntersect(innerCircle)) {
                        move.EnginePower = 1;
                        move.WheelTurn = -steering;
                        move.IsBrake = false;
                        return true;
                    }

                    if (rect.isIntersect(backWall) || rect.isIntersect(backSideWall)) {
                        move.IsBrake = false;
                        move.EnginePower = -1;
                        //move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, current.center, turningTo, -0.25 * Constants.tileSize));
                        move.WheelTurn = steering;
                        return true;
                    }

                    vv.position.draw(0xFF0000);
                    vv.rect.draw(0x0000FF);

                }
            }

            move.EnginePower = 0.5;
            move.WheelTurn = vehicle.steeringAngleForDirection(vehicle.stabilizationDir(turningFrom, current.center, turningTo, -0.25 * Constants.tileSize));
            move.IsBrake = false;
            return true;
        }
Пример #16
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;
        }
Пример #17
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;
        }
Пример #18
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;
            }
        }
Пример #19
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            if (tilePath.Count < 3)
                return false;

            var currentTile = MyStrategy.map.tileAt(vehicle.position);
            Vector target;
            Vector turningFrom;
            Vector turningTo;

            {

                var currentToFirst = currentTile.directionForTile(tilePath[0]).Value;
                var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value;
                var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value;

                if (currentToFirst != secondToThird) {
                    return false;
                }

                if (firstToSecond.isSameAxis(currentToFirst)) {
                    return false;
                }

                turningFrom = new Vector(currentToFirst);
                turningTo = new Vector(firstToSecond);

                target = tilePath[2].center - turningFrom * 0.5 * Constants.tileSize;

            }

            var vehicleToTarget = target - vehicle.position;

            if (vehicle.speed.length > 10 && vehicle.forward * (turningFrom + turningTo) > 0) {

                var steering = Math.Sign(turningFrom.angleTo(turningTo));

                Ray side = new Ray(
                               tilePath[0].center - turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5,
                               turningFrom * (Constants.tileSize - Constants.roadMargin)
                           );

                Ray back = new Ray(side.p2, turningTo * (Constants.tileSize - Constants.roadMargin));

                Circle backCircle = new Circle(back.p2 + turningFrom * Constants.roadMargin, Constants.roadMargin);

                Ray innerSide = new Ray(
                    currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5,
                    turningFrom * Constants.tileSize
                );

                Circle innerCircle = new Circle(innerSide.p2 + turningTo * Constants.roadMargin, Constants.roadMargin);

                side.draw(0x00FF00);
                back.draw(0x00FF00);
                backCircle.draw(0x00FF00);

                innerSide.draw(0x00FF00);
                innerCircle.draw(0x00FF00);

                var vv = new VirtualVehicle(vehicle);

                for (int i = 0; i < 100; ++i) {
                    vv.simulateTick(1.0, 0.0);

                    var rect = vv.rect;

                    if (rect.isIntersect(side) || rect.isIntersect(back) || rect.isIntersect(backCircle)) {

                        vv = new VirtualVehicle(vehicle);

                        for (int j = 0; j < 100; ++j) {
                            vv.simulateTick(1, steering);

                            if (rect.isIntersect(innerSide) || rect.isIntersect(innerCircle)) {
                                move.EnginePower = 1;
                                move.IsBrake = true;
                                move.WheelTurn = steering;
                                return true;
                            }
                        }

                        move.EnginePower = 1;
                        move.IsBrake = false;
                        move.WheelTurn = steering;
                        return true;
                    } else if (rect.isIntersect(innerSide) || rect.isIntersect(innerCircle)) {

                        vv = new VirtualVehicle(vehicle);

                        for (int j = 0; j < 100; ++j) {
                            vv.simulateTick(1, -steering);

                            if (rect.isIntersect(innerSide) || rect.isIntersect(innerCircle)) {
                                move.EnginePower = 1;
                                move.IsBrake = true;
                                move.WheelTurn = -steering;
                                return true;
                            }
                        }

                        move.EnginePower = 1;
                        move.IsBrake = false;
                        move.WheelTurn = -steering;
                        return true;
                    }

                    if (tilePath[2].rect.contains(vv.position)) {
                        move.EnginePower = 1;
                        move.IsBrake = false;
                        move.WheelTurn = vehicle.steeringAngleForDirection(vehicleToTarget);
                        return true;
                    }

                    rect.draw(0x0000FF);
                    vv.position.draw(0xFF0000);
                }

                move.EnginePower = 1;
                move.IsBrake = false;
                move.WheelTurn = vehicle.steeringAngleForDirection(vehicleToTarget);

                //new Ray(vehicle.position, vehicleToTarget).draw(0x00FFFF);

                return true;

            }

            if (vehicle.forward * vehicleToTarget < 0.5) {
                if (vehicle.speed.length > 10) {
                    move.IsBrake = true;
                }
                move.EnginePower = 0.3;
            } else {
                move.EnginePower = 1;
            }
            move.WheelTurn = vehicle.steeringAngleForDirection(vehicleToTarget);
            move.IsBrake = false;

            return true;
        }
Пример #20
0
        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
        }
Пример #21
0
        public void drive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            //defaults
            move.IsUseNitro = false;

            foreach (var strategy in strategies) {
                if (strategy.tryDrive(vehicle, tilePath, move)) {

                    Debug.print(vehicle.position + new Vector(15, 15), strategy.GetType().Name);

                    return;
                }
            }

            //throw new Exception("Do not have strategy for this situation");
        }
Пример #22
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);

                        }
                    }
                }
            }
        }
Пример #23
0
        public override bool tryDrive(Vehicle vehicle, List<Tile> tilePath, Move move)
        {
            if (tilePath.Count < 3)
                return false;

            var currentTile = MyStrategy.map.tileAt(vehicle.position);

            Vector turningTo;
            Vector turningFrom;

            {

                var currentToFirst = currentTile.directionForTile(tilePath[0]).Value;
                var firstToSecond = tilePath[0].directionForTile(tilePath[1]).Value;
                var secondToThird = tilePath[1].directionForTile(tilePath[2]).Value;

                if (currentToFirst != firstToSecond)
                    return false;

                if (firstToSecond.isSameAxis(secondToThird))
                    return false;

                if (tilePath.Count >= 4) {
                    if (tilePath[2].directionForTile(tilePath[3]).Value.back() == currentToFirst)
                        return false;
                }

                turningFrom = new Vector(currentToFirst);
                turningTo = new Vector(secondToThird);
            }

            if (vehicle.speed.length > 10 && vehicle.forward * turningFrom > 0.45) {
                var vv = new VirtualVehicle(vehicle);
                var steering = Math.Sign(turningFrom.angleTo(turningTo));

                var innerSide1 = Ray.line(
                    currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningFrom * Constants.tileSize * 0.5,
                    currentTile.center + turningTo * (Constants.tileSize * 0.5 - Constants.roadMargin) + turningFrom * Constants.tileSize * 0.5
                );

                //innerSide1.draw(0x00FF00);

                var innerSide2 = new Ray(innerSide1.position + turningFrom * Constants.tileSize, innerSide1.direction);

                //innerSide2.draw(0x00FF00);

                var innerCircle = new Circle(currentTile.center + (turningTo + turningFrom) * Constants.tileSize * 0.5 + turningFrom * Constants.tileSize, Constants.roadMargin);

                //innerCircle.draw(0x00FF00);

                var backWall = new Ray(tilePath[1].center + turningFrom * (Constants.tileSize * 0.5 - Constants.roadMargin) - turningTo * (Constants.tileSize * 0.5), turningTo * 2 * Constants.tileSize);

                //backWall.draw(0x00FF00);

                var outerSide = new Ray(currentTile.center - turningTo * (Constants.halfTileSize - Constants.roadMargin) - turningFrom * Constants.halfTileSize, turningFrom * Constants.tileSize * 3);

                //outerSide.draw(0x00FF00);

                for (int i = 0; i < 100; ++i) {
                    vv.simulateTick(1.0, steering);
                    if (vv.rect.isIntersect(innerSide1) || vv.rect.isIntersect(innerSide2))
                        break;

                    if (vv.rect.isIntersect(innerCircle))
                        break;

                    if (vv.rect.isIntersect(outerSide)) {
                        var target = currentTile.center + turningFrom * Constants.tileSize * 1.5;

                        move.WheelTurn = steering;
                        move.EnginePower = 1;
                        move.IsBrake = true;

                        return true;
                    }

                    if (vv.rect.isIntersect(backWall)) {
                        move.EnginePower = 1;
                        move.WheelTurn = steering;
                        move.IsBrake = true;
                        return true;
                    }

                    if (tilePath[2].rect.contains(vv.position)) {

                        // защита от слишком быстрого захода в поворот и ударения в заднюю стенку

                        for (int j = 0; j < 50; ++j) {

                            vv.simulateTick(1, steering);
                            if (vv.rect.isIntersect(backWall)) {
                                move.EnginePower = 1;
                                move.WheelTurn = steering;
                                move.IsBrake = true;
                                return true;
                            }

                            //vv.position.draw(0x00FF00);
                            //vv.rect.draw(0x0000FF);

                        }

                        move.EnginePower = 1;
                        move.WheelTurn = steering;
                        move.IsBrake = false;
                        return true;

                    }

                    //vv.position.draw(0xFF0000);
                    //vv.rect.draw(0x0000FF);
                }

            }

            move.WheelTurn = vehicle.steeringAngleForDirection((currentTile.center + turningFrom * Constants.tileSize * 1.5) - vehicle.position);
            move.EnginePower = 1;
            move.IsBrake = false;

            return true;
        }
Пример #24
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;
        }