using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; namespace MapGenerator { public static class DoubleArrayExtensionMethods { static Random _rnd = new Random(); /// /// Gets the coordinates of all the existing neigbors of a given tile /// /// The type of the doublearray contents /// The doublearray to work on /// The x-coordinate of the cell to get neigbors for /// The y-coordinate of the cell to get neighbors for /// An enumeration of the neigbors' coordinates public static IEnumerable GetNeighborCoordinates(this T[,] doubleArray, int x, int y, bool onlyXYaxis = false) { //for the column on the left to the column on the right of the tile for (int deltaX = -1; deltaX <= 1; deltaX++) { //for the row above to the row below the tile for (int deltaY = -1; deltaY <= 1; deltaY++) { //if we are only looking at the cells directly above/below and beside the cell //we skip diagonal neighbors if (onlyXYaxis && deltaY * deltaX != 0) { continue; } //the potential neighbor's coordinates int neighborX = x + deltaX; int neighborY = y + deltaY; //if the coordinate is within the map if (doubleArray.ContainsCoordinate(neighborX, neighborY)) { //and we aren't looking at the tile itself if (!(x == neighborX && y == neighborY)) { yield return new Point(neighborX, neighborY); } } } } } /// /// Gets the contents of the neighboring positions in the array /// /// The type of the doublearray /// The doublearray to work on /// The x-coordinate of the cell to get neigbors for /// The y-coordinate of the cell to get neighbors for /// An enumeration of the neighbors' contents public static IEnumerable GetNeighborContents(this T[,] doubleArray, int x, int y, bool onlyXYaxis = false) { foreach (var position in doubleArray.GetNeighborCoordinates(x, y, onlyXYaxis)) { yield return doubleArray[position.X, position.Y]; } } /// /// Determines whether a given coordinate set (given by a Point) is within a doublearray /// /// The type of the doublearray /// The doublearray to work on /// The coordinates of the cell to check for /// Whether the coordinates are within the double array public static bool ContainsCoordinate(this T[,] doubleArray, Point coordinates) { return coordinates.X >= 0 && coordinates.X < doubleArray.GetLength(0) && coordinates.Y >= 0 && coordinates.Y < doubleArray.GetLength(1); } /// /// Determines whether a given coordinate is within a doublearray /// /// The type of the doublearray /// The doublearray to work on /// The x-coordinate of the cell to check for /// The y-coordinate of the cell to check for /// Whether the coordinate is within the double array public static bool ContainsCoordinate(this T[,] doubleArray, int x, int y) { return x >= 0 && x < doubleArray.GetLength(0) && y >= 0 && y < doubleArray.GetLength(1); } /// /// Gets the positions of the bordercells in the doublearray /// /// The type of the doublearray /// The doublearray to work on /// How many cells in from the border to use (default 1) /// An enumeration of the positions of the bordercells in the doublearray public static IEnumerable GetBorderCellPositions(this T[,] doubleArray, int borderWidth = 1) { int width = doubleArray.GetLength(0); int height = doubleArray.GetLength(1); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (x < borderWidth || y < borderWidth || x > width - borderWidth - 1 || y > height - borderWidth - 1) { yield return new Point(x, y); } } } } /// /// Gets the coordinate of a random cell in the doublearray /// /// The type of the contents of the doublearray /// The doublearray to work on /// The coordinates of a random cell within the doublearray public static Point GetRandomCellPosition(this T[,] doubleArray) { return new Point(_rnd.Next(doubleArray.GetLength(0)), _rnd.Next(doubleArray.GetLength(1))); } /// /// Gets the coordinates of all cells in the doublearray /// /// The type of the contents of the doublearray /// The doublearray to work on /// The coordinates of a random cell within the doublearray public static IEnumerable GetAllPositions(this T[,] doubleArray) { int width = doubleArray.GetLength(0); int height = doubleArray.GetLength(1); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { yield return new Point(x, y); } } } public static bool F(T[,] array, Point p) { if (!array[p.X, p.Y].Equals(default(T))) { array[p.X, p.Y] = default(T); return true; } return false; } public static void FloodFill(this T[,] doubleArray, Point startingPosition, Func checkAndChangeTile, bool canMoveDiagonally = false, int iterations = int.MaxValue) { if (checkAndChangeTile(doubleArray, startingPosition)) { foreach (var neighbor in doubleArray.GetNeighborCoordinates(startingPosition.X, startingPosition.Y, !canMoveDiagonally)) { doubleArray.FloodFill(neighbor, checkAndChangeTile, canMoveDiagonally, iterations); } } } } }