public static double WheelTurnForEndZeroWheelTurnToPoint(this PCar car, Vector point, double finalAngle, double sign)
        {
            PCar physicCar = new PCar(car);

            int                 ticks      = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick));
            AngleReachEvent     angleReach = new AngleReachEvent(finalAngle);
            MoveToAngleFunction mover      = new MoveToAngleFunction(finalAngle);

            for (int i = 0; i < ticks; i++)
            {
                mover.Iteration(physicCar, 1);
                if (angleReach.Check(physicCar))
                {
                    break;
                }
            }

            Vector dir = physicCar.Speed.Length < 1 ? physicCar.Dir : physicCar.Dir * 0.8 + physicCar.Speed.Normalize() * 0.2;

            double distance = -(point - physicCar.Pos).Cross(dir);

            if (Math.Abs(distance) < 10)
            {
                return(0);
            }

            return(car.WheelTurn + sign * game.CarWheelTurnChangePerTick * Math.Sign(distance));
        }
        public static double WheelTurnForEndZeroWheelTurn(this PCar car, double finalAngle, double sign)
        {
            PCar physicCar = new PCar(car);
            int  ticks     = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick));

            physicCar.setWheelTurn(0);
            physicCar.Iteration(ticks);

            double angleDeviation = finalAngle.AngleDeviation(physicCar.Angle);

            if (sign < 0)
            {
                Vector v = Vector.sincos(finalAngle + Math.PI);
                double inverse90Angle = Math.Abs(v.X) > Math.Abs(v.Y) ?
                                        ((Math.Sign(v.X) - 1) * Math.PI / 2) :
                                        (Math.Sign(v.Y) * Math.PI / 2);

                if (Math.Abs(Math.Abs(v.X) - Math.Abs(v.Y)) < 1.0e-3)//45
                {
                    inverse90Angle = v.Angle;
                }

                double angleSub = inverse90Angle.AngleDeviation(physicCar.Angle);
                angleDeviation = finalAngle.AngleDeviation(physicCar.Angle + 2 * angleSub);
            }

            if (Math.Abs(angleDeviation) < game.CarRotationFrictionFactor)
            {
                return(0);
            }

            return(car.WheelTurn + game.CarWheelTurnChangePerTick * Math.Sign(angleDeviation));
        }
        public override bool Check(PCar car)
        {
            CollisionRect carRect = new CollisionRect(car);

            List <CollisionInfo> collisions = CollisionDetector.CheckCollision(carRect, collisionObjects);

            if (!collisions.HasCollision())
            {
                return(false);
            }

            foreach (CollisionInfo info in collisions)
            {
                if (!info.CollisionDeletected)
                {
                    continue;
                }

                Vector normal = info.NormalObj1;
                if (car.Dir.Dot(normal) > -1.0e-2)
                {
                    continue;
                }

                checkInfo = new Tuple <Vector, Vector>(info.Point, normal);
                return(true);
            }

            return(false);
        }
示例#4
0
        private bool hasReserveTicks(PCar iterCar, Vector needDirAngle)
        {
            MoveToPoint mover = null;

            if (null != needPos)
            {
                mover = new MoveToPoint(needPos, needDirAngle.Angle);
            }
            else
            {
                mover = new MoveToPoint(defaultPos);
            }

            PCar car = new PCar(iterCar);

            for (int tick = 0; tick < 5; tick++)
            {
                HashSet <IPhysicEvent> events = calculateTurnEvents(car, needDirAngle);

                if (events.ComeContaints(PhysicEventType.OutLine))
                {
                    return(false);
                }

                mover.Iteration(car, 1);
            }

            return(true);
        }
示例#5
0
        private int moveOnDistance(PCar car, Vector needDirAngle, double distance)
        {
            MoveToPoint mover = null;

            if (null != needPos)
            {
                mover = new MoveToPoint(needPos, needDirAngle.Angle);
            }
            else
            {
                mover = new MoveToPoint(defaultPos);
            }

            double speedL = car.Speed.Length;

            int addTick = 1;

            if (speedL > 1.0e-3)
            {
                addTick = (int)Math.Max(1, Math.Min(0.5 * distance / speedL, 1024));
            }
            else
            {
                addTick = 2;
            }

            mover.Iteration(car, addTick);
            return(addTick);
        }
示例#6
0
        /// avoid map crash
        private HashSet <IPhysicEvent> calculateAvoidMapCrashEvents(Move currentMove)
        {
            HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> {
                new MapCrashEvent()
            };

            if (null != moverSelfMapCrashEvent)
            {
                pEvents.Add(moverSelfMapCrashEvent.Copy());
            }

            if (null != passageLineEvent)
            {
                pEvents.Add(passageLineEvent.Copy());
            }

            PCar physicCar = new PCar(car, game);

            physicCar.setEnginePower(currentMove.EnginePower);
            physicCar.setWheelTurn(0);//currentMove.WheelTurn
            physicCar.setBrake(currentMove.IsBrake);

            PhysicEventsCalculator.calculateEvents(physicCar, new MoveWithOutChange(), pEvents, calculateAvoidSideCrashEventCheckEnd);

            return(pEvents);
        }
 public CollisionRect(PCar car)
 {
     this.Center = car.Pos;
     this.Dir    = car.Dir;
     this.Width  = car.Car.Width;
     this.Height = car.Car.Height;
     this.Points = calculatePoints();
 }
示例#8
0
        private bool calculateMoveEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick)
        {
            if (tick > maxCheckMoveCrashIterationCount)
            {
                return(true);
            }

            return(pEvents.ComeContaints(PhysicEventType.MapCrash) || pEvents.ComeContaints(PhysicEventType.ObjectsCrash));
        }
        public static PCar GetZeroWheelTurnCar(this PCar car)
        {
            PCar physicCar = new PCar(car);
            int  ticks     = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick));

            physicCar.setWheelTurn(0);
            physicCar.Iteration(ticks);

            return(physicCar);
        }
示例#10
0
        private bool calculateAvoidSideCrashEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick)
        {
            if (tick > maxCheckCrashIterationCount)
            {
                return(true);
            }

            //physicCar.setBrake(false);

            return(pEvents.ComeContaints(PhysicEventType.PassageLine) || pEvents.ComeContaints(PhysicEventType.MapCrash));
        }
示例#11
0
        private bool moveToAddPointEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick)
        {
            if (tick > maxIterationCount)
            {
                return(true);
            }

            return(pEvents.ComeContaints(PhysicEventType.MapCrash) ||
                   pEvents.ComeContaints(PhysicEventType.PassageLine) ||
                   pEvents.ComeContaints(PhysicEventType.ObjectsCrash));
        }
        public static double WheelTurnForEndZeroWheelTurn(this PCar car, Vector finalPos, double sign)
        {
            PCar physicCar = new PCar(car);
            int  ticks     = (int)Math.Abs(Math.Round(physicCar.WheelTurn / game.CarWheelTurnChangePerTick));

            physicCar.setWheelTurn(0);
            physicCar.Iteration(ticks);

            double finalAngle = (finalPos - car.Pos).Angle;

            return(car.WheelTurnForEndZeroWheelTurn(finalAngle, sign));
        }
示例#13
0
        private void avoidSideCrash(Move moveResult, Vector needDirAngle = null)
        {
            HashSet <IPhysicEvent> events = calculateAvoidMapCrashEvents(moveResult);

            IPhysicEvent passageLine  = events.ComeContaints(PhysicEventType.PassageLine) ? events.GetEvent(PhysicEventType.PassageLine) : null;
            IPhysicEvent mapCrash     = events.ComeContaints(PhysicEventType.MapCrash) ? events.GetEvent(PhysicEventType.MapCrash) : null;
            IPhysicEvent objectsCrash = events.ComeContaints(PhysicEventType.ObjectsCrash) ? events.GetEvent(PhysicEventType.ObjectsCrash) : null;
            IPhysicEvent crash        = (null != objectsCrash && objectsCrash.TickCome > 1) ? objectsCrash : mapCrash;

            if (null != crash)
            {
                int tickToPassageLine = (null != passageLine) ? passageLine.TickCome : maxIterationCount;

                if (crash.TickCome < tickToPassageLine)
                {
                    Vector dir = new Vector(dirMove.X, dirMove.Y);

                    PCar physicCar = crash.CarCome;
                    Tuple <Vector, Vector> crashInfo = crash.infoCome as Tuple <Vector, Vector>;
                    Logger.instance.Assert(null != crashInfo, "Can't get crash info");
                    Vector sideNormal = crashInfo.Item2;

                    double angle = dir.Angle.AngleDeviation(sideNormal.Angle);
                    if (Vector.sincos(car.Angle).Dot(dir) > 0 || 0 == angle)
                    {
                        angle = car.Angle.AngleDeviation(sideNormal.Angle);
                    }

                    bool notCurrentTurnSide = null != needDirAngle && sideNormal.Dot(needDirAngle) > 0;

                    if (!checkStrongParallel(crash) || notCurrentTurnSide)
                    {
                        moveResult.WheelTurn = car.WheelTurn - speedSign * Math.Sign(angle) * game.CarWheelTurnChangePerTick;
                    }

                    bool isParallel = Vector.sincos(car.Angle).Dot(sideNormal).LessDotWithAngle(Math.PI / 9); //20 degrees
                    isParallel |= physicCar.Dir.Dot(sideNormal).LessDotWithAngle(Math.PI / 9);                //20 degrees

                    int ticksToZeroEnginePower = (int)(Math.Abs(car.EnginePower) / game.CarEnginePowerChangePerTick);
                    if (!isParallel && speedSign > 0 && crash.TickCome < ticksToZeroEnginePower)
                    {
                        if (moveResult.EnginePower > 0.5)
                        {
                            moveResult.EnginePower -= game.CarEnginePowerChangePerTick;
                        }
                    }
                    if (!isParallel)
                    {
                        moveResult.IsBrake = moveResult.IsBrake || car.Speed() > Constant.MinBrakeSpeed;
                    }
                }
            }
        }
 public override bool Check(PCar car)
 {
     foreach (OilSlick stick in world.OilSlicks)
     {
         if ((car.Pos - new Vector(stick.X, stick.Y)).Length < stick.Radius)
         {
             car.traveledOnOil(stick);
             checkInfo = stick;
             return(true);
         }
     }
     return(false);
 }
示例#15
0
        private void move(Move moveResult)
        {
            PCar physicCar = new PCar(car, game);

            physicCar.setEnginePower(enginePowerSign);

            HashSet <IPhysicEvent> events = calculateMoveEvents(physicCar);

            if (events.ComeContaints(PhysicEventType.MapCrash) || events.ComeContaints(PhysicEventType.ObjectsCrash))
            {
                moveResult.WheelTurn = physicCar.WheelTurnForEndZeroWheelTurn(defaultPos, speedSign);
            }
        }
示例#16
0
        private bool calculateTurnMapCrashEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick)
        {
            if (tick > maxCheckRotateIterationCount)
            {
                return(true);
            }

            if (useBrakeForTurn)
            {
                physicCar.setBrake(physicCar.Speed.Length > Constant.MinBrakeSpeed);
            }

            return(pEvents.ComeContaints(PhysicEventType.PassageLine));
        }
示例#17
0
        private bool calculateTurnEventCheckEnd(PCar physicCar, HashSet <IPhysicEvent> pEvents, int tick)
        {
            if (tick > maxIterationCount)
            {
                return(true);
            }

            if (pEvents.ComeContaints(PhysicEventType.AngleReach) && !pEvents.Containts(PhysicEventType.SpeedReach))
            {
                pEvents.Add(new SpeedReachEvent());
            }

            return(pEvents.ComeContaints(PhysicEventType.SpeedReach));
        }
        public override bool Check(PCar car)
        {
            if (OutLine(car))
            {
                if (Math.Abs((car.LastPos - pos).Dot(normal)) < accuracity)
                {
                    return(true);
                }

                return(Math.Sign((car.Pos - pos).Dot(normal)) != Math.Sign((car.LastPos - pos).Dot(normal)));
            }

            return(false);
        }
示例#19
0
        private void turn(Move moveResult, Vector needDirAngle)
        {
            PCar iterCar = new PCar(car, game);

            iterCar.setEnginePower(enginePowerSign);

            Vector endPoint = endTile.ToVector(1 - dirMove.X, 1 - dirMove.Y);

            endPoint = endPoint + new Vector(dirMove.X, dirMove.Y) * game.TrackTileMargin;

            double speedSign = Math.Sign(Vector.sincos(car.Angle).Dot(new Vector(car.SpeedX, car.SpeedY)));

            HashSet <IPhysicEvent> events = calculateTurnEvents(iterCar, needDirAngle);

            IPhysicEvent passageLine = events.ComeContaints(PhysicEventType.PassageLine) ? events.GetEvent(PhysicEventType.PassageLine) : null;
            IPhysicEvent outLine     = events.ComeContaints(PhysicEventType.OutLine) ? events.GetEvent(PhysicEventType.OutLine) : null;
            IPhysicEvent speedReach  = events.ComeContaints(PhysicEventType.SpeedReach) ? events.GetEvent(PhysicEventType.SpeedReach) : null;

            if (null != passageLine && null != outLine)
            {
                int speedReachTick = null != speedReach ? speedReach.TickCome : maxIterationCount;

                if (speedReachTick * iterCar.CalculateBrakeFactor() > outLine.TickCome)
                {
                    moveResult.IsBrake = car.Speed() > Constant.MinBrakeSpeed;
                }
            }

            if (!hasReserveTicks(iterCar, needDirAngle))
            {
                HashSet <IPhysicEvent> crashEvents      = calculateTurnMapCrashEvents(iterCar, needDirAngle, moveResult.IsBrake);
                IPhysicEvent           mapBrakeCrash    = crashEvents.ComeContaints(PhysicEventType.ObjectsCrash) ? crashEvents.GetEvent(PhysicEventType.ObjectsCrash) : null;
                IPhysicEvent           passageLineBrake = crashEvents.ComeContaints(PhysicEventType.PassageLine) ? crashEvents.GetEvent(PhysicEventType.PassageLine) : null;

                //bool endMove = checkStrongParallel(mapBrakeCrash);
                int  tickToZeroWheelTurn = (int)Math.Round(Math.Abs(iterCar.WheelTurn / game.CarWheelTurnChangePerTick));
                bool nearEndAndCrash     = (null != mapBrakeCrash && null != passageLine && mapBrakeCrash.TickCome <= tickToZeroWheelTurn && passageLine.TickCome < tickToZeroWheelTurn);
                if ((null == mapBrakeCrash && null != passageLineBrake) || nearEndAndCrash)
                {
                    moveResult.WheelTurn = new PCar(car, game).WheelTurnForEndZeroWheelTurn(needDirAngle.Angle, speedSign);
                }
            }

            if (isMovedOutFromLine(iterCar, needDirAngle))
            {
                moveResult.WheelTurn = new PCar(car, game).WheelTurnForEndZeroWheelTurn(needDirAngle.Angle, speedSign);
            }
        }
示例#20
0
        public void Iteration(PCar car, int iterationCount)
        {
            for (int i = 0; i < iterationCount; i++)
            {
                if (intersecOildStickEvent.Check(car))
                {
                    car.traveledOnOil(intersecOildStickEvent.InfoForCheck as OilSlick);
                }

                double speedSign = Math.Sign(car.Dir.Dot(car.Speed));
                double wheelTurn = car.WheelTurnForEndZeroWheelTurn(angle, speedSign);
                car.setWheelTurn(wheelTurn);

                car.Iteration(1);
            }
        }
示例#21
0
        public PCar(PCar physicCar) : this(physicCar.car, physicCar.game)
        {
            wheelTurn        = physicCar.wheelTurn;
            idealWheelTurn   = physicCar.idealWheelTurn;
            enginePower      = physicCar.enginePower;
            idealEnginePower = physicCar.idealEnginePower;

            pos        = physicCar.pos;
            lastPos    = physicCar.lastPos;
            spd        = physicCar.spd;
            angle      = physicCar.angle;
            dir        = physicCar.dir;
            angleSpeed = physicCar.angleSpeed;
            nitroTicks = physicCar.nitroTicks;
            oilTicks   = physicCar.oilTicks;
            brake      = physicCar.brake;
        }
示例#22
0
        /// Move to Additional Point
        private void moveToAdditionalPoint(double needAngle)
        {
            if (null == additionalPoints)
            {
                return;
            }

            int minTicks = int.MaxValue;

            foreach (Tuple <Vector, double> data in additionalPoints)
            {
                Vector point = data.Item1;

                IPhysicEvent           passageLineEvent = new PassageLineEvent(Vector.sincos(needAngle), point, 0);
                HashSet <IPhysicEvent> pEvents          = new HashSet <IPhysicEvent> {
                    new MapCrashEvent(),
                    passageLineEvent
                };

                if (null != moverSelfMapCrashEvent)
                {
                    pEvents.Add(moverSelfMapCrashEvent.Copy());
                }

                PCar physicCar = new PCar(car, game);
                PhysicEventsCalculator.calculateEvents(physicCar, new MoveToPoint(point, needAngle), pEvents, moveToAddPointEventCheckEnd);

                if (pEvents.ComeContaints(PhysicEventType.MapCrash) || pEvents.ComeContaints(PhysicEventType.ObjectsCrash) ||
                    !pEvents.ComeContaints(PhysicEventType.PassageLine))
                {
                    continue;
                }

                if (passageLineEvent.CarCome.Pos.GetDistanceTo(point) > data.Item2)
                {
                    continue;
                }

                if (passageLineEvent.TickCome < minTicks)
                {
                    needPos = point;
                }
            }
        }
示例#23
0
        private HashSet <IPhysicEvent> calculateTurnMapCrashEvents(PCar iterCar, Vector needDirAngle, bool isBrake)
        {
            HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> {
                passageLineEvent.Copy()
            };

            if (null != moverSelfMapCrashEvent)
            {
                pEvents.Add(moverSelfMapCrashEvent.Copy());
            }

            PCar physicCar = new PCar(iterCar);

            useBrakeForTurn = isBrake;
            physicCar.setBrake(isBrake);
            PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(needDirAngle.Angle), pEvents, calculateTurnMapCrashEventCheckEnd);

            return(pEvents);
        }
示例#24
0
        /// Turn
        private HashSet <IPhysicEvent> calculateTurnEvents(PCar iterCar, Vector needDirAngle)
        {
            HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> {
                passageLineEvent.Copy(),
                                   outLineEvent.Copy(),
                                   angleReachEvent.Copy()
            };

            PCar physicCar = new PCar(iterCar);

            PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(needDirAngle.Angle), pEvents, calculateTurnEventCheckEnd);

            if (!pEvents.Containts(PhysicEventType.SpeedReach))
            {
                pEvents.Add(new SpeedReachEvent());
            }

            return(pEvents);
        }
示例#25
0
        ///Move
        private HashSet <IPhysicEvent> calculateMoveEvents(PCar iterCar)
        {
            HashSet <IPhysicEvent> pEvents = new HashSet <IPhysicEvent> {
                new MapCrashEvent()
            };

            if (null != moverSelfMapCrashEvent)
            {
                pEvents.Add(moverSelfMapCrashEvent.Copy());
            }

            PCar physicCar = new PCar(iterCar);

            /*if (null != needPos) {
             * PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(Math.Atan2(dirMove.Y, dirMove.X)), pEvents, calculateMoveEventCheckEnd);
             * } else {*/
            PhysicEventsCalculator.calculateEvents(physicCar, new MoveToAngleFunction(car.GetAbsoluteAngleTo(defaultPos.X, defaultPos.Y)), pEvents, calculateMoveEventCheckEnd);
            //}

            return(pEvents);
        }
        public static void calculateEvents(PCar physicCar, IPhysicMoveFunction moveFunc, HashSet <IPhysicEvent> pEvents, CheckCalculateEnd checkEnd)
        {
            for (int tick = 0; tick < maxSaveIterationCount; tick++)
            {
                foreach (IPhysicEvent pEvent in pEvents)
                {
                    if (!pEvent.IsCome && pEvent.Check(physicCar))
                    {
                        pEvent.SetCome(physicCar, tick, pEvent.InfoForCheck);
                    }
                }

                if (checkEnd(physicCar, pEvents, tick))
                {
                    return;
                }

                moveFunc.Iteration(physicCar, 1);
            }

            Logger.instance.Assert(false, "Please check delegate: CheckCalculateEnd.");
        }
示例#27
0
        public void Iteration(PCar car, int iterationCount)
        {
            for (int i = 0; i < iterationCount; i++)
            {
                if (intersecOildStickEvent.Check(car))
                {
                    car.traveledOnOil(intersecOildStickEvent.InfoForCheck as OilSlick);
                }

                double speedSign = Math.Sign(car.Dir.Dot(car.Speed));
                if (double.IsNaN(finalAngle))
                {
                    car.WheelTurnForEndZeroWheelTurn(point, speedSign);
                }
                else
                {
                    car.setWheelTurn(car.WheelTurnForEndZeroWheelTurnToPoint(point, finalAngle, speedSign));
                }

                car.Iteration(1);
            }
        }
示例#28
0
        private bool isMovedOutFromLine(PCar iterCar, Vector needDirAngle)
        {
            if (outLineEvent.OutLine(iterCar))
            {
                return(false);
            }

            MoveToPoint mover = null;

            if (null != needPos)
            {
                mover = new MoveToPoint(needPos, needDirAngle.Angle);
            }
            else
            {
                mover = new MoveToPoint(defaultPos);
            }

            PCar carToAngle = new PCar(iterCar);
            MoveToAngleFunction moveToAngle = new MoveToAngleFunction(needDirAngle.Angle);
            int ticksToAngle = 0;

            for (; ticksToAngle < 100; ticksToAngle++)
            {
                moveToAngle.Iteration(carToAngle, 1);
                if (angleReachEvent.Check(carToAngle))
                {
                    break;
                }
            }

            PCar car = new PCar(iterCar);

            mover.Iteration(car, ticksToAngle);

            return(outLineEvent.OutLine(car));
        }
 public bool OutLine(PCar car)
 {
     return(Math.Abs((car.Pos - pos).Dot(normal)) > accuracity);
 }
        public override bool Check(PCar car)
        {
            TilePos carPos = new TilePos(car.Pos.X, car.Pos.Y);

            return(carPos != tile);
        }