public override void execute(Move move)
        {
            TileDir dirMove = path[offset].DirOut;
            TileDir dirEnd  = path[1 + offset].DirOut;
            TilePos endTile = path[1 + offset].Pos;

            MovingCalculator calculator = new MovingCalculator();

            calculator.setupEnvironment(car, game, world);
            calculator.setupMapInfo(dirMove, path[0].Pos, path[1 + offset].Pos);

            calculator.setupDefaultAction(GetWayEnd(path[1 + offset].Pos, dirEnd.Negative() + dirMove.Negative() * 2));

            Vector endDir = new Vector(dirEnd.X - dirMove.X, dirEnd.Y - dirMove.Y).Normalize();

            calculator.setupAngleReach(endDir);
            calculator.setupPassageLine(GetWayEnd(endTile, dirEnd, 1.0), new Vector(dirEnd.X + dirMove.X, dirEnd.Y + dirMove.Y).Normalize(), 0.75);

            if (0 != offset)
            {
                calculator.setupAdditionalPoints(additionalPoints);
            }

            Dictionary <TilePos, TileDir[]> selfMap = new Dictionary <TilePos, TileDir[]>();

            for (int i = 0; i <= offset; i++)
            {
                if (path[i].DirIn == path[i].DirOut)
                {
                    selfMap.Add(path[i].Pos, new TileDir[2] {
                        dirMove.PerpendicularLeft(), dirMove.PerpendicularRight()
                    });
                }
                else
                {
                    selfMap.Add(path[i].Pos, new TileDir[3] {
                        path[i].DirIn, path[i].DirOut.Negative(), path[i].DirIn.Negative() + path[i].DirOut
                    });
                }
            }
            selfMap.Add(endTile, new TileDir[2] {
                dirEnd.Negative(), dirEnd + dirMove.Negative()
            });

            calculator.setupSelfMapCrash(selfMap);

            Move needMove = calculator.calculateTurn(endDir);

            move.IsBrake     = needMove.IsBrake;
            move.EnginePower = needMove.EnginePower;
            move.WheelTurn   = needMove.WheelTurn;
        }
Пример #2
0
        protected PathCheckResult checkAround(int offset = 0)
        {
            if (2 + offset >= path.Count)
            {
                return(PathCheckResult.Unknown);
            }

            TilePos posIn  = path[1 + offset].Pos;
            TilePos posOut = path[2 + offset].Pos;

            TileDir dirIn  = path[1 + offset].DirIn;
            TileDir dirOut = path[2 + offset].DirOut;

            if (null == dirOut || dirOut == TileDir.Zero)
            {
                return(PathCheckResult.Unknown);
            }

            bool isLine = dirIn == path[1 + offset].DirOut || path[2 + offset].DirIn == dirOut;

            if (!isLine && dirIn == dirOut.Negative() && posIn != posOut)
            {
                return(PathCheckResult.Yes);
            }
            else
            {
                return(PathCheckResult.No);
            }
        }
Пример #3
0
        private Vector EndSidePos()
        {
            TilePos pos    = path[0].Pos;
            TileDir dir    = path[0].DirOut;
            TileDir normal = new TileDir(0);

            for (int i = 1; i < Math.Min(5, path.Count); i++)
            {
                if (null == path[i].DirOut)
                {
                    pos = path[0].Pos + dir * 4;
                    break;
                }

                if (path[i].DirIn != path[i].DirOut)
                {
                    normal = path[i].DirOut;
                    break;
                }

                pos = path[i].Pos;
                dir = path[i].DirIn;
            }

            if (normal == dir.Negative())
            {
                normal = dir;
            }

            return(EndSidePos(pos, dir, normal.Negative()));
        }
Пример #4
0
        private double tilePriority(TileDir dirIn, TileDir dirOut, TileDir nextDirIn, TileDir nextDirOut)
        {
            if (nextDirIn.Negative() == nextDirOut)
            {
                return(-4.25);
            }

            if (dirIn.Negative() == dirOut)
            {
                return(-1);
            }

            if (dirIn == dirOut)//line
            {
                return(0.42);
            }

            if (null == nextDirOut || nextDirIn == nextDirOut)//turn
            {
                return(-0.6);
            }

            if (dirIn == nextDirOut.Negative() && dirOut == nextDirIn)//around
            {
                return(-2.5);
            }
            else if (dirIn == nextDirOut && dirOut == nextDirIn)//snake
            {
                return(0.45);
            }

            return(0);
        }
Пример #5
0
        public override bool valid()
        {
            offset = 0;
            TileDir dir = path[offset].DirOut;

            double minAngle = (path[offset].DirOut == path[offset].DirIn) ? (11 * Math.PI / 18) : (16 * Math.PI / 18);

            double angle = car.GetAngleTo(car.X + dir.X, car.Y + dir.Y);

            if (Math.Abs(angle) > minAngle)
            {
                return(true);
            }

            offset = 1;
            TileDir dirIn  = path[offset].DirIn;
            TileDir dirOut = path[offset].DirOut;

            if (dirIn == dirOut.Negative())
            {
                return(true);
            }

            return(false);
        }
        public override void execute(Move move)
        {
            TileDir dirMove = path[0].DirOut;
            TileDir dirEnd  = path[2].DirOut;

            MovingCalculator calculator = new MovingCalculator();

            calculator.setupEnvironment(car, game, world);
            calculator.setupMapInfo(dirMove, path[0].Pos, path[2].Pos);
            calculator.setupDefaultAction(GetWayEnd(path[2].Pos, dirEnd.Negative()));

            Vector endDir = new Vector(dirEnd.X + dirMove.X, dirEnd.Y + dirMove.Y).Normalize();

            calculator.setupAngleReach(endDir);
            calculator.setupPassageLine(GetWayEnd(path[2].Pos, TileDir.Zero), new Vector(dirMove.X, dirMove.Y), 0.5);

            Dictionary <TilePos, TileDir[]> selfMap = new Dictionary <TilePos, TileDir[]>();

            for (int i = 0; i < 2; i++)
            {
                selfMap.Add(path[i].Pos, new TileDir[2] {
                    dirMove.PerpendicularLeft(), dirMove.PerpendicularRight()
                });
            }
            selfMap.Add(path[2].Pos, new TileDir[2] {
                dirEnd + dirMove.Negative(), dirEnd
            });

            calculator.setupSelfMapCrash(selfMap);
            calculator.setupAdditionalPoints(this.additionalPoints);

            Move needMove = calculator.calculateTurn(endDir);

            move.IsBrake     = needMove.IsBrake;
            move.EnginePower = needMove.EnginePower;
            move.WheelTurn   = needMove.WheelTurn;
        }
Пример #7
0
        public override void execute(Move move)
        {
            TileDir dirMove = path[offset].DirOut;

            Vector dir = new Vector(dirMove.X, dirMove.Y);

            Vector carPos = new Vector(car.X, car.Y);
            Vector endPos = GetWayEnd(path[offset].Pos, TileDir.Zero);

            endPos.X = car.X * Math.Abs(dir.X) + endPos.X * Math.Abs(dir.Y);
            endPos.Y = car.Y * Math.Abs(dir.Y) + endPos.Y * Math.Abs(dir.X);

            Physic.MovingCalculator calculator = new Physic.MovingCalculator();
            calculator.setupEnvironment(car, game, world);
            calculator.setupMapInfo(dirMove, path[0].Pos, null);
            calculator.useBackward();

            if (0 == offset)
            {
                TileDir nextDirOut = path[1].DirOut;
                Vector  nextDir    = new Vector(nextDirOut.X, nextDirOut.Y);

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

                if (speedSign > 0 || nextDirOut == dirMove)
                {
                    endPos   -= dir * 2 * game.TrackTileSize;
                    needBrake = speedSign > 0;
                }
                else if (nextDirOut.Negative() == dirMove)
                {
                    endPos -= dir * 2 * game.TrackTileSize;
                    needChangeEnginePower = true;
                    needBrake             = car.Speed() > 8;
                }
                else
                {
                    endPos   -= dir * 2 * game.TrackTileSize;
                    endPos   += nextDir * car.Height;
                    needBrake = car.Speed() > 10;
                }

                calculator.setupAngleReach(nextDir);
                calculator.setupDefaultAction(endPos);

                Move needMove = calculator.calculateMove();
                move.IsBrake     = needMove.IsBrake || needBrake;
                move.EnginePower = needMove.EnginePower;
                move.WheelTurn   = needMove.WheelTurn;

                if (needChangeEnginePower)
                {
                    double distance = (GetWayEnd(path[1].Pos, dirMove.Negative()) - carPos).Dot(dir);
                    move.EnginePower = -game.CarEnginePowerChangePerTick - distance / game.TrackTileSize;
                }
            }
            else
            {
                endPos -= dir * 2 * game.TrackTileSize;
                double distance = (carPos - GetWayEnd(path[offset].Pos, dirMove)).Dot(dir);

                calculator.setupAngleReach(dir);
                calculator.setupDefaultAction(endPos);
                Move needMove = calculator.calculateMove();
                move.IsBrake     = needMove.IsBrake || car.Speed() > 8;
                move.EnginePower = game.CarEnginePowerChangePerTick + distance / game.TrackTileSize;
                move.WheelTurn   = needMove.WheelTurn;
            }
        }