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);
}
}
}
}
}