/// <summary> /// Create an empty map /// </summary> public GameMap(int width, int height) { Squares = new MapSquare[width][]; for (int x = 0; x < width; x++) { Squares[x] = new MapSquare[height]; for (int y = 0; y < height; y++) Squares[x][y] = new MapSquare(); } }
public GameMap(XDocument xml, List<Company> companies) { int width = int.Parse(xml.Root.Attribute("width").Value); int height = int.Parse(xml.Root.Attribute("height").Value); Squares = new MapSquare[width][]; for (int x = 0; x < width; x++) Squares[x] = new MapSquare[height]; foreach (XElement elementOn in xml.Root.Elements("square")) { int x = int.Parse(elementOn.Attribute("x").Value); int y = int.Parse(elementOn.Attribute("y").Value); MapSquare square = new MapSquare(elementOn); Squares[x][y] = square; } }
/// <summary> /// Return a direction to the adjoining tile that is the only or straight direction. Returns NONE if there /// are multiple choices and both are a turn (ie entering the base of a T). /// </summary> /// <param name="direction">The vehicle direction (used to avoid u-turns)</param> /// <returns>The direction to the adjoining tile.</returns> public MapSquare.COMPASS_DIRECTION GetStraightNext(MapSquare.COMPASS_DIRECTION direction) { switch (Direction) { case DIRECTION.NORTH_SOUTH: return direction; case DIRECTION.EAST_WEST: return direction; case DIRECTION.INTERSECTION: return direction; case DIRECTION.NORTH_UTURN: return MapSquare.COMPASS_DIRECTION.SOUTH; case DIRECTION.EAST_UTURN: return MapSquare.COMPASS_DIRECTION.WEST; case DIRECTION.SOUTH_UTURN: return MapSquare.COMPASS_DIRECTION.NORTH; case DIRECTION.WEST_UTURN: return MapSquare.COMPASS_DIRECTION.EAST; case DIRECTION.T_NORTH: return direction == MapSquare.COMPASS_DIRECTION.SOUTH ? MapSquare.COMPASS_DIRECTION.NONE : direction; case DIRECTION.T_EAST: return direction == MapSquare.COMPASS_DIRECTION.WEST ? MapSquare.COMPASS_DIRECTION.NONE : direction; case DIRECTION.T_SOUTH: return direction == MapSquare.COMPASS_DIRECTION.NORTH ? MapSquare.COMPASS_DIRECTION.NONE : direction; case DIRECTION.T_WEST: return direction == MapSquare.COMPASS_DIRECTION.EAST ? MapSquare.COMPASS_DIRECTION.NONE : direction; case DIRECTION.CURVE_NE: return direction == MapSquare.COMPASS_DIRECTION.NORTH ? MapSquare.COMPASS_DIRECTION.EAST : MapSquare.COMPASS_DIRECTION.SOUTH; case DIRECTION.CURVE_NW: return direction == MapSquare.COMPASS_DIRECTION.NORTH ? MapSquare.COMPASS_DIRECTION.WEST : MapSquare.COMPASS_DIRECTION.SOUTH; case DIRECTION.CURVE_SE: return direction == MapSquare.COMPASS_DIRECTION.SOUTH ? MapSquare.COMPASS_DIRECTION.EAST : MapSquare.COMPASS_DIRECTION.NORTH; case DIRECTION.CURVE_SW: return direction == MapSquare.COMPASS_DIRECTION.SOUTH ? MapSquare.COMPASS_DIRECTION.WEST : MapSquare.COMPASS_DIRECTION.NORTH; default: throw new ApplicationException("illegal direction"); } }
/// <summary> /// Return a direction to a random tile adjoining this one that's legal. U-turn only /// if no alternatives. /// </summary> /// <param name="direction">The vehicle direction (used to avoid u-turns)</param> /// <returns>The direction to the adjoining tile.</returns> public MapSquare.COMPASS_DIRECTION GetRandomNext(MapSquare.COMPASS_DIRECTION direction) { // for T and 4-way MapSquare.COMPASS_DIRECTION[] choices; switch (Direction) { case DIRECTION.NORTH_SOUTH: return direction; case DIRECTION.EAST_WEST: return direction; case DIRECTION.INTERSECTION: choices = new[] { MapSquare.COMPASS_DIRECTION.NORTH, MapSquare.COMPASS_DIRECTION.EAST, MapSquare.COMPASS_DIRECTION.SOUTH, MapSquare.COMPASS_DIRECTION.WEST}; break; case DIRECTION.NORTH_UTURN: return MapSquare.COMPASS_DIRECTION.SOUTH; case DIRECTION.EAST_UTURN: return MapSquare.COMPASS_DIRECTION.WEST; case DIRECTION.SOUTH_UTURN: return MapSquare.COMPASS_DIRECTION.NORTH; case DIRECTION.WEST_UTURN: return MapSquare.COMPASS_DIRECTION.EAST; case DIRECTION.T_NORTH: choices = new[] { MapSquare.COMPASS_DIRECTION.NORTH, MapSquare.COMPASS_DIRECTION.EAST, MapSquare.COMPASS_DIRECTION.WEST}; break; case DIRECTION.T_EAST: choices = new[] { MapSquare.COMPASS_DIRECTION.NORTH, MapSquare.COMPASS_DIRECTION.EAST, MapSquare.COMPASS_DIRECTION.SOUTH}; break; case DIRECTION.T_SOUTH: choices = new[] { MapSquare.COMPASS_DIRECTION.EAST, MapSquare.COMPASS_DIRECTION.SOUTH, MapSquare.COMPASS_DIRECTION.WEST}; break; case DIRECTION.T_WEST: choices = new[] { MapSquare.COMPASS_DIRECTION.NORTH, MapSquare.COMPASS_DIRECTION.SOUTH, MapSquare.COMPASS_DIRECTION.WEST}; break; case DIRECTION.CURVE_NE: return direction == MapSquare.COMPASS_DIRECTION.NORTH ? MapSquare.COMPASS_DIRECTION.EAST : MapSquare.COMPASS_DIRECTION.SOUTH; case DIRECTION.CURVE_NW: return direction == MapSquare.COMPASS_DIRECTION.NORTH ? MapSquare.COMPASS_DIRECTION.WEST : MapSquare.COMPASS_DIRECTION.SOUTH; case DIRECTION.CURVE_SE: return direction == MapSquare.COMPASS_DIRECTION.SOUTH ? MapSquare.COMPASS_DIRECTION.EAST : MapSquare.COMPASS_DIRECTION.NORTH; case DIRECTION.CURVE_SW: return direction == MapSquare.COMPASS_DIRECTION.SOUTH ? MapSquare.COMPASS_DIRECTION.WEST : MapSquare.COMPASS_DIRECTION.NORTH; default: throw new ApplicationException("illegal direction"); } // have to choose from 3 or 4 - but not the direction came from int index = rand.Next(choices.Length - 1); MapSquare.COMPASS_DIRECTION ptUturn = MapSquare.UTurn(direction); foreach (MapSquare.COMPASS_DIRECTION choice in choices) { if (choice == ptUturn) continue; if (index == 0) return choice; index--; } throw new ApplicationException("bad random number"); }
/// <summary> /// Trim the map so only have 2 tiles of park outside of road limits. /// </summary> public void Trim() { // reduce columns first (map is column major) int startX = 0; for (int xOn=0; xOn<Width; xOn++) { bool nonPark = false; for (int yOn=0; yOn<Height; yOn++) if (Squares[xOn][yOn].Tile.Type != MapTile.TYPE.PARK) { nonPark = true; break; } if (nonPark) break; startX = xOn; } int endX = Width - 1; for (int xOn=Width-1; xOn>startX; xOn--) { bool nonPark = false; for (int yOn = 0; yOn < Height; yOn++) if (Squares[xOn][yOn].Tile.Type != MapTile.TYPE.PARK) { nonPark = true; break; } if (nonPark) break; endX = xOn; } startX = Math.Max(0, startX - 1); endX = Math.Min(Width - 1, endX + 1); if (startX > 0 || endX < Width-1) { MapSquare[][] squares = new MapSquare[endX - startX + 1][]; for (int index = 0; index < squares.Length; index++) squares[index] = Squares[startX + index]; Squares = squares; } // now the rows. int startY = 0; for (int yOn = 0; yOn < Height; yOn++) { bool nonPark = false; for (int xOn = 0; xOn < Width; xOn++) if (Squares[xOn][yOn].Tile.Type != MapTile.TYPE.PARK) { nonPark = true; break; } if (nonPark) break; startY = yOn; } int endY = Height - 1; for (int yOn = Height - 1; yOn > startY; yOn--) { bool nonPark = false; for (int xOn = 0; xOn < Width; xOn++) if (Squares[xOn][yOn].Tile.Type != MapTile.TYPE.PARK) { nonPark = true; break; } if (nonPark) break; endY = yOn; } startY = Math.Max(0, startY - 1); endY = Math.Min(Height - 1, endY + 1); if (startY > 0 || endY < Height - 1) { for (int xOn = 0; xOn < Width; xOn++) { MapSquare[] column = new MapSquare[endY - startY + 1]; for (int yOn = 0; yOn < column.Length; yOn++) column[yOn] = Squares[xOn][startY + yOn]; Squares[xOn] = column; } } }
/// <summary> /// Rotate the map 90 degrees. /// </summary> public void Rotate90() { int width = Height; int height = Width; MapSquare[][] squares = new MapSquare[width][]; for (int x = 0; x < width; x++) { squares[x] = new MapSquare[height]; for (int y = 0; y < height; y++) squares[x][y] = Squares[y][width - x - 1]; } Squares = squares; }
/// <summary> /// Add rows to the bottom of the map. /// </summary> /// <param name="num">Number of rows to add.</param> public void AddRows(int num) { int height = Height; for (int x = 0; x < Width; x++) { MapSquare[] column = new MapSquare[height + num]; for (int y = 0; y < height; y++) column[y] = Squares[x][y]; for (int y = height; y < height + num; y++) column[y] = new MapSquare(); Squares[x] = column; } }
/// <summary> /// Add columns to the right of the map. /// </summary> /// <param name="num">Number of columns to add.</param> public void AddColumns(int num) { MapSquare[][] squares = new MapSquare[Width + num][]; for (int x = 0; x < Width; x++) squares[x] = Squares[x]; for (int x = Width; x < Width + num; x++) { squares[x] = new MapSquare[Height]; for (int y = 0; y < Height; y++) squares[x][y] = new MapSquare(); } Squares = squares; }
public void SetTileLocation(MapSquare square, Point ptTile, MapSquare.COMPASS_DIRECTION direction) { switch (square.Tile.Direction) { case MapTile.DIRECTION.NORTH_SOUTH: case MapTile.DIRECTION.EAST_WEST: case MapTile.DIRECTION.INTERSECTION: case MapTile.DIRECTION.T_NORTH: case MapTile.DIRECTION.T_EAST: case MapTile.DIRECTION.T_SOUTH: case MapTile.DIRECTION.T_WEST: switch (direction) { case MapSquare.COMPASS_DIRECTION.NORTH: Location = new BoardLocation(new Point(ptTile.X*TileMovement.UNITS_PER_TILE + addMiddleFarLane, ptTile.Y*TileMovement.UNITS_PER_TILE + addMiddleTile), TileMovement.GetMove(MapSquare.COMPASS_DIRECTION.NORTH, MapSquare.COMPASS_DIRECTION.NORTH)); return; case MapSquare.COMPASS_DIRECTION.EAST: Location = new BoardLocation(new Point(ptTile.X*TileMovement.UNITS_PER_TILE + addMiddleTile, ptTile.Y*TileMovement.UNITS_PER_TILE + addMiddleFarLane), TileMovement.GetMove(MapSquare.COMPASS_DIRECTION.EAST, MapSquare.COMPASS_DIRECTION.EAST)); return; case MapSquare.COMPASS_DIRECTION.SOUTH: Location = new BoardLocation(new Point(ptTile.X*TileMovement.UNITS_PER_TILE + addMiddleNearLane, ptTile.Y*TileMovement.UNITS_PER_TILE + addMiddleTile), TileMovement.GetMove(MapSquare.COMPASS_DIRECTION.SOUTH, MapSquare.COMPASS_DIRECTION.SOUTH)); return; case MapSquare.COMPASS_DIRECTION.WEST: Location = new BoardLocation(new Point(ptTile.X * TileMovement.UNITS_PER_TILE + addMiddleTile, (ptTile.Y * TileMovement.UNITS_PER_TILE + addMiddleNearLane)), TileMovement.GetMove(MapSquare.COMPASS_DIRECTION.WEST, MapSquare.COMPASS_DIRECTION.WEST)); return; } return; } }
public static TileMovement GetMove(MapSquare.COMPASS_DIRECTION start, MapSquare.COMPASS_DIRECTION end) { switch (start) { case MapSquare.COMPASS_DIRECTION.NORTH: switch (end) { case MapSquare.COMPASS_DIRECTION.NORTH: return North; case MapSquare.COMPASS_DIRECTION.EAST: return TurnNE; case MapSquare.COMPASS_DIRECTION.SOUTH: return Unorth; case MapSquare.COMPASS_DIRECTION.WEST: return TurnNW; } break; case MapSquare.COMPASS_DIRECTION.EAST: switch (end) { case MapSquare.COMPASS_DIRECTION.NORTH: return TurnEN; case MapSquare.COMPASS_DIRECTION.EAST: return East; case MapSquare.COMPASS_DIRECTION.SOUTH: return TurnES; case MapSquare.COMPASS_DIRECTION.WEST: return Ueast; } break; case MapSquare.COMPASS_DIRECTION.SOUTH: switch (end) { case MapSquare.COMPASS_DIRECTION.NORTH: return Usouth; case MapSquare.COMPASS_DIRECTION.EAST: return TurnSE; case MapSquare.COMPASS_DIRECTION.SOUTH: return South; case MapSquare.COMPASS_DIRECTION.WEST: return TurnSW; } break; case MapSquare.COMPASS_DIRECTION.WEST: switch (end) { case MapSquare.COMPASS_DIRECTION.NORTH: return TurnWN; case MapSquare.COMPASS_DIRECTION.EAST: return Uwest; case MapSquare.COMPASS_DIRECTION.SOUTH: return TurnWS; case MapSquare.COMPASS_DIRECTION.WEST: return West; } break; } throw new ApplicationException("unknown direction(s)"); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public SignalSquare(int x, int y, MapSquare square) { X = x; Y = y; Square = square; }