Exemple #1
0
        private static bool IsClear(TileIndex topCorner, int width, int height)
        {
            if (!AITile.IsBuildableRectangle(topCorner, width, height))
            {
                return(false);
            }

            var xx = AIMap.GetTileX(topCorner);
            var yy = AIMap.GetTileY(topCorner);

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    var testTile = topCorner + AIMap.GetTileIndex(x, y);
                    if (!AIMap.IsValidTile(testTile))
                    {
                        return(false);
                    }

                    var slope = AITile.GetSlope(testTile);
                    if (slope != AITile.SLOPE_FLAT)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemple #2
0
        private static RailStationInfo FindPlaceForStation(TileIndex tile, int platformLength, int platformCount)
        {
            var xx = AIMap.GetTileX(tile);
            var yy = AIMap.GetTileY(tile);

            for (var step = 1; step < 15; step++)
            {
                for (var i = 0; i < step * 2; i++)
                {
                    var x     = xx - step;
                    var y     = yy + Helper.Alternate(i);
                    var tile2 = AIMap.GetTileIndex(x, y);
                    var test  = RailStationBuilder.TestPlaceForStation(tile2, platformLength, platformCount);
                    if (test != null)
                    {
                        return(test);
                    }

                    x     = xx - Helper.Alternate(i);
                    y     = yy + step;
                    tile2 = AIMap.GetTileIndex(x, y);
                    test  = RailStationBuilder.TestPlaceForStation(tile2, platformLength, platformCount);
                    if (test != null)
                    {
                        return(test);
                    }

                    x     = xx + step;
                    y     = yy + Helper.Alternate(i);
                    tile2 = AIMap.GetTileIndex(x, y);
                    test  = RailStationBuilder.TestPlaceForStation(tile2, platformLength, platformCount);
                    if (test != null)
                    {
                        return(test);
                    }

                    x     = xx + Helper.Alternate(i);
                    y     = yy - step;
                    tile2 = AIMap.GetTileIndex(x, y);
                    test  = RailStationBuilder.TestPlaceForStation(tile2, platformLength, platformCount);
                    if (test != null)
                    {
                        return(test);
                    }
                }
            }

            return(null);
        }
Exemple #3
0
        private static RailStationInfo TestPlaceForStation(TileIndex tile, int platformLength, int platformCount)
        {
            var buffer      = 4;
            var clearLength = platformLength;
            var clearWidth  = platformCount;

            var tile2 = tile - AIMap.GetTileIndex(clearWidth / 2, clearLength / 2);

            if (RailStationBuilder.IsClear(tile2, clearWidth, clearLength + buffer))
            {
                return(new RailStationInfo()
                {
                    tile = tile - AIMap.GetTileIndex(clearWidth / 2, clearLength / 2), direction = AIRail.RAILTRACK_NW_SE, entryNearTopCorner = false
                });
            }

            tile2 = tile - AIMap.GetTileIndex(clearLength / 2, clearWidth / 2);
            if (RailStationBuilder.IsClear(tile2, clearLength + buffer, clearWidth))
            {
                return(new RailStationInfo()
                {
                    tile = tile - AIMap.GetTileIndex(clearLength / 2, clearWidth / 2), direction = AIRail.RAILTRACK_NE_SW, entryNearTopCorner = false
                });
            }

            tile2 = tile - AIMap.GetTileIndex(clearWidth / 2, (clearLength / 2) + buffer);
            if (RailStationBuilder.IsClear(tile2, clearWidth, clearLength + buffer))
            {
                return(new RailStationInfo()
                {
                    tile = tile - AIMap.GetTileIndex(clearWidth / 2, clearLength / 2), direction = AIRail.RAILTRACK_NW_SE, entryNearTopCorner = true
                });
            }

            tile2 = tile - AIMap.GetTileIndex((clearLength / 2) + buffer, clearWidth / 2);
            if (RailStationBuilder.IsClear(tile2, clearLength + buffer, clearWidth))
            {
                return(new RailStationInfo()
                {
                    tile = tile - AIMap.GetTileIndex(clearLength / 2, clearWidth / 2), direction = AIRail.RAILTRACK_NE_SW, entryNearTopCorner = true
                });
            }

            return(null);
        }
Exemple #4
0
        private static RoadStationInfo TestPlaceForStation(TileIndex tile)
        {
            if (AITile.IsBuildable(tile) && (AITile.GetSlope(tile) == AITile.SLOPE_FLAT))
            {
                var other = tile + AIMap.GetTileIndex(0, 1);
                if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT))
                {
                    return(new RoadStationInfo()
                    {
                        tile = tile, entryPoint = other
                    });
                }

                other = tile + AIMap.GetTileIndex(1, 0);
                if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT))
                {
                    return(new RoadStationInfo()
                    {
                        tile = tile, entryPoint = other
                    });
                }

                other = tile + AIMap.GetTileIndex(0, -1);
                if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT))
                {
                    return(new RoadStationInfo()
                    {
                        tile = tile, entryPoint = other
                    });
                }

                other = tile + AIMap.GetTileIndex(-1, 0);
                if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT))
                {
                    return(new RoadStationInfo()
                    {
                        tile = tile, entryPoint = other
                    });
                }
            }

            return(null);
        }
Exemple #5
0
        public void FindRouteTest1()
        {
            using (var world = new OpenTTD.Testing.TestWorld(20, 20))
            {
                var path = RailBuilder.FindPath(AIMap.GetTileIndex(10, 10), AIMap.GetTileIndex(15, 15), AIMap.GetTileIndex(9, 10));
                foreach (var item in path)
                {
                    Debug.WriteLine(item.Tile);
                }

                Assert.AreEqual(12, path.Count);
                Assert.AreEqual(AIMap.GetTileIndex(15, 15), path[0].Tile);
                Assert.AreEqual(AIMap.GetTileIndex(14, 14), path[2].Tile);
                Assert.AreEqual(AIMap.GetTileIndex(13, 13), path[4].Tile);
                Assert.AreEqual(AIMap.GetTileIndex(12, 12), path[6].Tile);
                Assert.AreEqual(AIMap.GetTileIndex(11, 11), path[8].Tile);
                Assert.AreEqual(AIMap.GetTileIndex(10, 10), path[10].Tile);
                Assert.AreEqual(AIMap.GetTileIndex(9, 10), path[11].Tile);
            }
        }
Exemple #6
0
        public void CalculateAngleTest1()
        {
            using (var world = new OpenTTD.Testing.TestWorld(20, 20))
            {
                /*   /\
                 *  /\/
                 * /\/
                 * \/    */
                var currentTile = AIMap.GetTileIndex(10, 10);
                var cameFrom    = new PathInfo(
                    AIMap.GetTileIndex(9, 10),
                    1,
                    1,
                    BuildType.Basic,
                    new PathInfo(
                        AIMap.GetTileIndex(8, 1),
                        1,
                        1,
                        BuildType.Basic,
                        null
                        )
                    );

                double actual = RailBuilder.CalculateAngle(currentTile, cameFrom.Tile, cameFrom.Previous);
                Assert.AreEqual(0.0, actual);

                /*  /\
                 * /\/
                 * \/\
                 * /\/
                 * \/    */
                cameFrom = new PathInfo(
                    AIMap.GetTileIndex(9, 10),
                    1,
                    1,
                    BuildType.Basic,
                    new PathInfo(
                        AIMap.GetTileIndex(9, 9),
                        1,
                        1,
                        BuildType.Basic,
                        new PathInfo(
                            AIMap.GetTileIndex(8, 9),
                            1,
                            1,
                            BuildType.Basic,
                            null
                            )
                        )
                    );

                actual = RailBuilder.CalculateAngle(currentTile, cameFrom.Tile, cameFrom.Previous);
                Assert.AreEqual(0.0, actual);

                /*   /\
                 *  /\/
                 *  \/\
                 *  /\/
                 * /\/
                 * \/    */
                cameFrom = new PathInfo(
                    AIMap.GetTileIndex(9, 10),
                    1,
                    1,
                    BuildType.Basic,
                    new PathInfo(
                        AIMap.GetTileIndex(8, 10),
                        1,
                        1,
                        BuildType.Basic,
                        new PathInfo(
                            AIMap.GetTileIndex(8, 9),
                            1,
                            1,
                            BuildType.Basic,
                            new PathInfo(
                                AIMap.GetTileIndex(7, 9),
                                1,
                                1,
                                BuildType.Basic,
                                null
                                )
                            )
                        )
                    );

                actual = RailBuilder.CalculateAngle(currentTile, cameFrom.Tile, cameFrom.Previous);
                Assert.AreEqual(1.0, actual);

                /*  /\
                 * /\/\
                 * \/\/
                 *  \/    */
                cameFrom = new PathInfo(
                    AIMap.GetTileIndex(9, 10),
                    1,
                    1,
                    BuildType.Basic,
                    new PathInfo(
                        AIMap.GetTileIndex(9, 9),
                        1,
                        1,
                        BuildType.Basic,
                        new PathInfo(
                            AIMap.GetTileIndex(10, 9),
                            1,
                            1,
                            BuildType.Basic,
                            null
                            )
                        )
                    );

                actual = RailBuilder.CalculateAngle(currentTile, cameFrom.Tile, cameFrom.Previous);
                Assert.AreEqual(100.0, actual);
            }
        }
Exemple #7
0
        public static RailStationBuildResult BuildStationNear(TileIndex tile, int platformLength, int platformCount = 2)
        {
            var stationTile = RailStationBuilder.FindPlaceForStation(tile, platformLength, platformCount);

            if (stationTile != null)
            {
                AILog.Info("Build " + stationTile.tile + ", " + stationTile.direction);
                var good = AIRail.BuildRailStation(stationTile.tile, stationTile.direction, platformCount, platformLength, AIStation.STATION_NEW);
                if (good)
                {
                    TileIndex entryTile;
                    int[]     matrix;
                    if (stationTile.direction == AIRail.RAILTRACK_NW_SE)
                    {
                        if (stationTile.entryNearTopCorner)
                        {
                            /*   \
                             \/\
                             \/   */
                            entryTile = stationTile.tile + AIMap.GetTileIndex(0, 0);
                            matrix    = new int[] { -1, 0, 0, -1 };
                        }
                        else
                        {
                            /*  /\
                            \/\
                            \   */
                            entryTile = stationTile.tile + AIMap.GetTileIndex(1, platformLength - 1);
                            matrix    = new int[] { 1, 0, 0, 1 };
                        }
                    }
                    else if (stationTile.direction == AIRail.RAILTRACK_NE_SW)
                    {
                        if (stationTile.entryNearTopCorner)
                        {
                            /*   /
                             *  /\/
                             \/   */
                            entryTile = stationTile.tile + AIMap.GetTileIndex(0, 1);
                            matrix    = new int[] { 0, -1, 1, 0 };
                        }
                        else
                        {
                            /*   /\
                            *   /\/
                            *    /    */
                            entryTile = stationTile.tile + AIMap.GetTileIndex(platformLength - 1, 0);
                            matrix    = new int[] { 0, 1, -1, 0 };
                        }
                    }
                    else
                    {
                        return(null);
                    }

                    /* |      |
                     +00-01-+
                     *  02 03
                     * 04 05 06 07
                     *  08 09
                     *  10 11
                     *
                     */

                    var tiles = new TileIndex[] {
                        entryTile + RailStationBuilder.GetTransformedTileIndex(0, 0, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(-1, 0, matrix),

                        entryTile + RailStationBuilder.GetTransformedTileIndex(0, 1, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(-1, 1, matrix),

                        entryTile + RailStationBuilder.GetTransformedTileIndex(1, 2, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(0, 2, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(-1, 2, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(-2, 2, matrix),

                        entryTile + RailStationBuilder.GetTransformedTileIndex(0, 3, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(-1, 3, matrix),

                        entryTile + RailStationBuilder.GetTransformedTileIndex(0, 4, matrix),
                        entryTile + RailStationBuilder.GetTransformedTileIndex(-1, 4, matrix),
                    };

                    // Exit rail
                    AIRail.BuildRail(
                        tiles[0],
                        tiles[2],
                        tiles[10]);

                    // Entry rail
                    AIRail.BuildRail(
                        tiles[1],
                        tiles[3],
                        tiles[11]);

                    // Signals
                    AIRail.BuildSignal(tiles[2], tiles[0], AIRail.SIGNALTYPE_PBS);
                    AIRail.BuildSignal(tiles[3], tiles[1], AIRail.SIGNALTYPE_PBS);
                    AIRail.BuildSignal(tiles[9], tiles[11], AIRail.SIGNALTYPE_PBS_ONEWAY);

                    //Depot
                    TileIndex depotTile = AIMap.TILE_INVALID;
                    if (AIRail.BuildRailDepot(tiles[4], tiles[5]))
                    {
                        depotTile = tiles[4];
                        RailStationBuilder.BuildIntersection(tiles[2], tiles[4], tiles[6], tiles[8]);
                        RailStationBuilder.BuildIntersection(tiles[3], tiles[5], tiles[9]);
                    }
                    else
                    {
                        if (AIRail.BuildRailDepot(tiles[7], tiles[6]))
                        {
                            depotTile = tiles[7];
                            RailStationBuilder.BuildIntersection(tiles[3], tiles[5], tiles[7], tiles[9]);
                            RailStationBuilder.BuildIntersection(tiles[2], tiles[6], tiles[8]);
                        }
                    }

                    return(new RailStationBuildResult()
                    {
                        StationID = AIStation.GetStationID(stationTile.tile),
                        ExitCloser = tiles[8],
                        ExitFarther = tiles[10],
                        EntryCloser = tiles[9],
                        EntryFarther = tiles[11],
                        DepotTile = depotTile
                    });
                }
            }

            return(null);
        }
Exemple #8
0
 private static TileIndex GetTransformedTileIndex(int x, int y, int[] matrix)
 {
     return(AIMap.GetTileIndex(x * matrix[0] + y * matrix[1], x * matrix[2] + y * matrix[3]));
 }
Exemple #9
0
        private static void BuildIntersection(TileIndex tile1, TileIndex tile2, TileIndex tile3, TileIndex tile4 = null)
        {
            var tile1x = AIMap.GetTileX(tile1);
            var tile1y = AIMap.GetTileY(tile1);
            var tile2x = AIMap.GetTileX(tile2);
            var tile2y = AIMap.GetTileY(tile2);
            var tile3x = AIMap.GetTileX(tile3);
            var tile3y = AIMap.GetTileY(tile3);

            var x = (int)((tile1x + tile2x + tile3x) / 3.0 + 0.5);
            var y = (int)((tile1y + tile2y + tile3y) / 3.0 + 0.5);

            var center = AIMap.GetTileIndex(x, y);

            var nwTile = AIMap.GetTileIndex(x, y - 1);
            var neTile = AIMap.GetTileIndex(x - 1, y);
            var swTile = AIMap.GetTileIndex(x + 1, y);
            var seTile = AIMap.GetTileIndex(x, y + 1);

            if (tile4 != null)
            {
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NE_SW); // /
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_SE); // \
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_NE); // - (upper)
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_SW_SE); // - (lower)
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_SW); // | left
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NE_SE); // | right
                return;
            }

            if ((tile1 != nwTile) && (tile2 != nwTile) && (tile3 != nwTile))
            {
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NE_SW); // /
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_SW_SE); // - (lower)
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NE_SE); // | right
                return;
            }

            if ((tile1 != neTile) && (tile2 != neTile) && (tile3 != neTile))
            {
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_SE); // \
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_SW_SE); // - (lower)
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_SW); // | left
                return;
            }

            if ((tile1 != swTile) && (tile2 != swTile) && (tile3 != swTile))
            {
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_SE); // \
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_NE); // - (upper)
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NE_SE); // | right
                return;
            }

            if ((tile1 != seTile) && (tile2 != seTile) && (tile3 != seTile))
            {
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NE_SW); // /
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_NE); // - (upper)
                AIRail.BuildRailTrack(center, AIRail.RAILTRACK_NW_SW); // | left
                return;
            }
        }
Exemple #10
0
        internal static List <PathInfo> GetNeighbors(TileIndex tile, PathInfo cameFrom, Action <TileIndex, string> sign = null)
        {
            var oldcost = cameFrom.Cost;
            var result  = new List <PathInfo>();
            var isFlat  = AITile.GetSlope(tile) == AITile.SLOPE_FLAT;
            var dirs    = new int[][] { new int[] { 0, 1 }, new int[] { 0, -1 }, new int[] { 1, 0 }, new int[] { -1, 0 } };
            var oldDir  = (cameFrom.Previous != null) ? Helper.GetDirection(cameFrom.Previous.Tile, tile) : Direction.None;

            foreach (var dir in dirs)
            {
                var x = dir[0];
                var y = dir[1];
                if (cameFrom.Tile == tile + AIMap.GetTileIndex(x, y))
                {
                    continue;
                }

                var newDir = Helper.GetDirection(tile, tile + AIMap.GetTileIndex(x, y));

                var isCoast   = AITile.IsCoastTile(tile);
                var straight  = newDir == oldDir;
                var maxLength = 20;

                bool lastWasExistingBridge = false;

                TileIndex neighbor;
                for (var length = 1; AIMap.IsValidTile(neighbor = tile + AIMap.GetTileIndex(x * length, y * length)) && length <= maxLength; length++)
                {
                    if (AIBridge.IsBridgeTile(neighbor))
                    {
                        var otherEnd  = AIBridge.GetOtherBridgeEnd(neighbor);
                        var bridgeDir = Helper.GetDirection(neighbor, otherEnd);

                        if (newDir == bridgeDir)
                        {
                            length += AIMap.DistanceManhattan(neighbor, otherEnd);
                            lastWasExistingBridge = true;
                            continue;
                        }
                    }
                    else if (AIRoad.IsRoadTile(neighbor) && (lastWasExistingBridge || (length == 1)))
                    {
                        result.Add(new PathInfo(
                                       neighbor,
                                       length,
                                       oldcost + (length * 0.5),
                                       length > 1 ? BuildType.Bridge : BuildType.Basic,
                                       cameFrom
                                       ));
                        break;
                    }

                    lastWasExistingBridge = false;
                    if (isCoast)
                    {
                        if (!straight)
                        {
                            break;
                        }

                        if (AITile.IsWaterTile(neighbor))
                        {
                            continue;
                        }
                    }

                    double multiplier = 1;
                    if (AITile.IsFarmTile(neighbor) || AITile.IsRockTile(neighbor) || AITile.IsRoughTile(tile))
                    {
                        // Make farms, rocks, etc more expensive.
                        multiplier *= 1.1;
                    }

                    if (AITile.IsBuildable(neighbor))
                    {
                        if (isCoast)
                        {
                            result.Add(new PathInfo(
                                           neighbor,
                                           length,
                                           oldcost + ((length * multiplier * 2)),
                                           BuildType.Bridge,
                                           cameFrom
                                           ));

                            break;
                        }
                        else if ((isFlat && cameFrom.Length == 1) || ((length == 1) && straight))
                        {
                            result.Add(new PathInfo(
                                           neighbor,
                                           length,
                                           oldcost + ((length * multiplier)),
                                           length == 1 ? BuildType.Basic : BuildType.Bridge,
                                           cameFrom
                                           ));

                            break;
                        }
                    }
                    else if (!(
                                 (AIRoad.IsRoadTile(neighbor) || AIRoad.IsRoadTile(neighbor) || AITile.IsWaterTile(neighbor)) &&
                                 (AITile.GetSlope(neighbor) == AITile.SLOPE_FLAT) &&
                                 !AIStation.IsValidStation(AIStation.GetStationID(neighbor))))
                    {
                        // Can't built over
                        break;
                    }
                }
            }

            return(result);
        }
Exemple #11
0
        internal static List <PathInfo> GetNeighbors(TileIndex tile, PathInfo cameFrom, Action <TileIndex, string> sign = null)
        {
            var oldcost = cameFrom.Cost;
            var result  = new List <PathInfo>();
            var isFlat  = AITile.GetSlope(tile) == AITile.SLOPE_FLAT;
            var dirs    = new int[][] { new int[] { 0, 1 }, new int[] { 0, -1 }, new int[] { 1, 0 }, new int[] { -1, 0 } };
            var oldDir  = Helper.GetDirection(tile, cameFrom.Previous.Tile);

            foreach (var dir in dirs)
            {
                var x = dir[0];
                var y = dir[1];
                if (cameFrom.Tile == tile + AIMap.GetTileIndex(x, y))
                {
                    continue;
                }

                var newDir = Helper.GetDirection(tile + AIMap.GetTileIndex(x, y), tile);

                var isCoast   = AITile.IsCoastTile(tile);
                var straight  = newDir == oldDir;
                var maxLength = isCoast ? 20 : (straight ? 5 : 1);

                TileIndex neighbor;
                for (var length = 1; AIMap.IsValidTile(neighbor = tile + AIMap.GetTileIndex(x * length, y * length)) && length <= maxLength; length++)
                {
                    if (isCoast)
                    {
                        if (!straight)
                        {
                            break;
                        }

                        if (AITile.IsWaterTile(neighbor))
                        {
                            continue;
                        }
                    }

                    double multiplier = 1;
                    if (AITile.IsFarmTile(neighbor) || AITile.IsRockTile(neighbor) || AITile.IsRoughTile(tile))
                    {
                        // Make farms, rocks, etc more expensive.
                        multiplier *= 1.1;
                    }

                    if (AITile.IsBuildable(neighbor))
                    {
                        double angleFactor = RailBuilder.CalculateAngle(neighbor, tile, cameFrom.Previous);
                        if (isCoast)
                        {
                            result.Add(new PathInfo(
                                           neighbor,
                                           length,
                                           oldcost + ((length * multiplier * 2) + angleFactor),
                                           BuildType.Bridge,
                                           cameFrom
                                           ));

                            break;
                        }
                        else if ((isFlat && cameFrom.Length == 1) || ((length == 1) && straight))
                        {
                            result.Add(new PathInfo(
                                           neighbor,
                                           length,
                                           oldcost + ((length * multiplier) + angleFactor),
                                           length == 1 ? BuildType.Basic : BuildType.Bridge,
                                           cameFrom
                                           ));

                            break;
                        }
                    }
                    else if (!(
                                 (AIRail.IsRailTile(neighbor) || AIRoad.IsRoadTile(neighbor) || AITile.IsWaterTile(neighbor)) &&
                                 (AITile.GetSlope(neighbor) == AITile.SLOPE_FLAT) &&
                                 !AIStation.IsValidStation(AIStation.GetStationID(neighbor))))
                    {
                        // Can't built over
                        break;
                    }
                }
            }

            return(result);
        }
Exemple #12
0
 public Point(int x, int y)
 {
     this.Tile = AIMap.GetTileIndex(x, y);
     this.X    = x;
     this.Y    = Y;
 }