Example #1
0
        public void Update(double updateFactor)
        {
            if (speed.SumComponentSqrs() > 0.0D)
                position += speed * updateFactor;

            if (game.CarMovementAirFrictionFactor > 0)
            {
                double lastMovementTransferFactor = Math.Pow(1.0D - game.CarMovementAirFrictionFactor, updateFactor);
                speed *= lastMovementTransferFactor;
            }

            if (game.CarLengthwiseMovementFrictionFactor > 0.0D)
            {
                double velocityLength = speed.Magnitude;
                if (velocityLength > 0.0D)
                {

                    double velocityChange = game.CarLengthwiseMovementFrictionFactor * updateFactor;

                    if (velocityChange >= velocityLength)
                    {
                        speed = new Vector(0.0D, 0.0D);
                    }
                    else if (velocityChange > 0.0D)
                    {
                        speed *= (1.0D - velocityChange / velocityLength);
                    }
                }
            }
        }
Example #2
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;
        }
Example #3
0
 public DynamicState(
     Vector position, Vector velocity, Vector force, double angle, double angularVelocity, double torque)
 {
     this.velocity = velocity;
     this.force = force;
     this.angularVelocity = angularVelocity;
     this.torque = torque;
 }
Example #4
0
        public SimulatedPosition(Car self, Game game)
        {
            this.game = game;

            position = new Vector(self.X,self.Y);
            speed =  new Vector(self.SpeedX,self.SpeedY);
            enginePower = self.EnginePower;
        }
Example #5
0
 public DynamicState(DynamicState state)
 {
     this.position = state.position;
     this.angle = state.angle;
     this.velocity = state.velocity;
     this.force = state.force;
     this.angularVelocity = state.angularVelocity;
     this.torque = state.torque;
 }
Example #6
0
        public Arc(Vector position, double _raduis, double fromAngle, double toAngle)
            : this()
        {
            while (fromAngle > Math.PI)
                fromAngle -= Math.PI * 2;
            while (fromAngle < -Math.PI)
                fromAngle += Math.PI * 2;

            while (toAngle > Math.PI)
                toAngle -= Math.PI * 2;
            while (toAngle < -Math.PI)
                toAngle += Math.PI * 2;

            this.position = position;
            this.radius = _raduis;
            this.fromAngle = fromAngle;
            this.toAngle = toAngle;
        }
Example #7
0
 public void setMedianVelocity(Vector medianVelocity)
 {
     currentState.medianVelocity = medianVelocity;
 }
Example #8
0
 public void setForce(Vector force)
 {
     currentState.force = force;
 }
Example #9
0
 public DynamicState()
 {
     this.velocity = new Vector(0.0D, 0.0D);
     this.medianVelocity = new Vector(0.0D, 0.0D);
     this.force = new Vector(0.0D, 0.0D);
 }
Example #10
0
        public static LinkedList<TilePathNode> findPathFromWaypoints(int[][] waypoints, RoadMap roadMap, Vector startPosition, Vector startForward, int skipWaypoints = 1)
        {
            var path = new LinkedList<TilePathNode>();

            var lastTile = roadMap.tileAt(startPosition);

            for (int i = skipWaypoints, iend = waypoints.Length * 2 + 1; i < iend; ++i) {
                var currentTile = roadMap.tileAt(waypoints[i % waypoints.Length][0], waypoints[i % waypoints.Length][1]);

                Vector startDir;
                if (i == skipWaypoints) { //initial
                    startDir = startForward;
                } else {
                    startDir = new Vector(0, 0);
                }

                var mpath = findPathBetween(lastTile, currentTile, startDir);

                foreach (TilePathNode node in mpath) {
                    path.AddLast(node);
                }

                if (path.Last != null) {
                    var lastNode = path.Last.Value;
                    lastNode.waypointIndex = i % waypoints.Length;
                    path.Last.Value = lastNode;
                }
                lastTile = currentTile;
            }

            return path;
        }
Example #11
0
 public Ray(Vector position, Vector direction)
     : this()
 {
     this.position = position;
     this.direction = direction;
 }
Example #12
0
 public Rect(Vector a, Vector b)
 {
     min = new Vector(Math.Min(a.x, b.x), Math.Min(a.y, b.y));
     max = new Vector(Math.Max(a.x, b.x), Math.Max(a.y, b.y));
 }
Example #13
0
 public void setVelocity(Vector velocity)
 {
     currentState.velocity = velocity;
 }
Example #14
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;
        }
Example #15
0
 public Vector stabilizationDir(Vector baseDir, Vector sideCenter, Vector sideDir, double sidePosition)
 {
     var dist = (position - sideCenter) * sideDir + sidePosition;
     return baseDir - sideDir * dist / Constants.tileSize;
 }
Example #16
0
 public double cross(Vector o)
 {
     return x * o.y - y * o.x;
 }
Example #17
0
        public double angleTo(Vector o)
        {
            double relAngle = o.angle - angle;
            while (relAngle > Math.PI)
                relAngle -= 2 * Math.PI;

            while (relAngle < -Math.PI)
                relAngle += 2 * Math.PI;

            return relAngle;
        }
Example #18
0
        public static bool Equals(Vector a, Vector b)
        {
            const double E = 0.0001;

            return Math.Abs(a.x - b.x) < E && Math.Abs(a.y - b.y) < E;
        }
Example #19
0
 public bool contains(Vector point)
 {
     return point.x <= max.x && point.x >= min.x && point.y <= max.y && point.y >= min.y;
 }
Example #20
0
 public void setPosition(Vector position)
 {
     currentState.position = new Vector(position);
 }
Example #21
0
 public static Ray line(Vector p1, Vector p2)
 {
     return new Ray(p1, p2 - p1);
 }
Example #22
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;
        }
Example #23
0
 public double steeringAngleForDirection(Vector direction)
 {
     return forward.angleTo(direction) * 4 * Math.Sign(speed * forward);
 }
Example #24
0
        public double lineDistance(Vector p)
        {
            var p1 = this.p1;
            var p2 = this.p2;

            return Math.Abs((p2.y - p1.y) * p.x - (p2.x - p1.x) * p.y + p2.x * p1.y - p2.y * p1.x)
            /
            (p1 - p2).length;
        }
Example #25
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;
        }
Example #26
0
 public PathNode(Vector pos)
 {
     position = pos;
     importance = 0;
 }
Example #27
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;
        }
Example #28
0
 public PathNode(Vector pos, double importance)
 {
     position = pos;
     this.importance = importance;
 }
Example #29
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;
        }
Example #30
0
        public static LinkedList<TilePathNode> findPathBetween(Tile from, Tile to, Vector startDirection)
        {
            var roadMap = from.roadMap;

            var cost = new double[roadMap.width, roadMap.height];
            for (int x = 0; x < roadMap.width; ++x) {
                for (int y = 0; y < roadMap.height; ++y) {
                    cost[x, y] = double.MaxValue;
                }
            }

            var backDir = new AxisDirection[roadMap.width, roadMap.height];
            var speedDir = new Vector[roadMap.width, roadMap.height];

            var queue = new Queue<Tile>();
            queue.Enqueue(from);

            cost[from.posX, from.posY] = 0;
            speedDir[from.posX, from.posY] = startDirection;

            while (queue.Count > 0) {
                var current = queue.Dequeue();

                foreach (AxisDirection dir in Enum.GetValues(typeof(AxisDirection))) {
                    if (current.canGoInDirection(dir)) {
                        var next = current.nextTileInDirection(dir);
                        if (next != null) {

                            double nextCost = cost[current.posX, current.posY] + 1;
                            if (speedDir[current.posX, current.posY] * new Vector(dir) < 0.01)
                                nextCost += 1;

                            if (cost[next.posX, next.posY] > nextCost) {
                                cost[next.posX, next.posY] = nextCost;
                                backDir[next.posX, next.posY] = dir.back();
                                speedDir[next.posX, next.posY] = new Vector(dir);

                                if (!queue.Contains(next))
                                    queue.Enqueue(next);
                            }
                        }
                    }
                }

            }

            var list = new LinkedList<TilePathNode>();

            {
                var current = to;

                if (cost[to.posX, to.posY] == -1)
                    return list; // SHEEIT, UNKNOWN TILES

                while (current != from) {
                    list.AddFirst(new TilePathNode(current));
                    current = current.nextTileInDirection(backDir[current.posX, current.posY]);
                    if (current == null)
                        return list;
                }
            }

            return list;
        }