Beispiel #1
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;
                    }
                }
            }
        }
Beispiel #2
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);
            }
        }
Beispiel #3
0
        private bool checkStrongParallel(IPhysicEvent mapCrash)
        {
            if (null == mapCrash)
            {
                return(false);
            }

            Tuple <Vector, Vector> crashInfo = mapCrash.infoCome as Tuple <Vector, Vector>;

            if (null == crashInfo)
            {
                return(false);
            }

            Vector sideNormal = crashInfo.Item2;

            bool isStrongParallel = Vector.sincos(car.Angle).Dot(sideNormal).LessDotWithAngle(Math.PI / 18); //10 degrees

            isStrongParallel &= mapCrash.CarCome.Dir.Dot(sideNormal).LessDotWithAngle(Math.PI / 18);         //10 degrees

            return(isStrongParallel);
        }