namespace Squish { /// /// An object which contains a two-dimensional grid of values. /// /// The type of values. public class Grid : IEnumerable { #region Constructors /// /// An object which contains a two-dimensional grid of values. /// /// The width. /// The height. public Grid(int width, int height) { if (width < 0) width = 0; // Having a width or height of 0 won't be usable, if (height < 0) height = 0; // but at least the value ranges would be "expected" _values = new T[height][]; for (int i = 0; i < height; i++) _values[i] = new T[width]; Width = width; Height = height; } #endregion #region Indexers /// /// Gets or sets a value. /// /// The X coordinate. /// The Y coordinate. /// The value. public T this[int x, int y] { get { return _values[y][x]; } set { _values[y][x] = value; } } #endregion // Variables private readonly T[][] _values; // Properties #region Width /// /// Gets a value which indicates the width. /// public int Width { get; private set; } #endregion #region Height /// /// Gets a value which indicates the height. /// public int Height { get; private set; } #endregion // Methods #region Transpose /// /// Returns a new object which is the transpose copy of this grid. /// /// The grid. public Grid Transpose() { Grid result = new Grid(Height, Width); for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[x][y] = _values[y][x]; return result; } #endregion #region Flip /// /// Returns a new object which is a horizontal or vertical copy of this grid. /// /// Whether to perform a horizontal flip. /// Whether to perform a vertical flip. /// The grid. public Grid Flip(bool horizontal, bool vertical) { Grid result = new Grid(Width, Height); if (horizontal && vertical) { for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[y][x] = _values[Height - y - 1][Width - x - 1]; return result; } if (horizontal) { for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[y][x] = _values[y][Width - x - 1]; return result; } if (vertical) { for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[y][x] = _values[Height - y - 1][x]; return result; } for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[y][x] = _values[y][x]; return result; } #endregion #region Rotate /// /// Returns a new object which is the rotation copy of this grid. /// /// Whether to rotate clockwise or anti-clockwise. /// The grid. public Grid Rotate(bool clockwise) { Grid result = new Grid(Height, Width); if (clockwise) { for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[x][y] = _values[Height - y - 1][x]; } else { for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[x][y] = _values[y][Width - x - 1]; } return result; } #endregion #region Copy /// /// Returns a new object which is a copy of the grid. /// /// The grid. public Grid Copy() { Grid result = new Grid(Width, Height); for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) result._values[y][x] = _values[y][x]; return result; } #endregion #region Slice /// /// Returns a new object which is a subregion of the grid. /// /// The region. /// The grid. public Grid Slice(Rectangle region) { region = Rectangle.Intersect(region, new Rectangle(0, 0, Width, Height)); Grid result = new Grid(region.Width, region.Height); for (int y = 0; y < region.Height; y++) for (int x = 0; x < region.Width; x++) result._values[y][x] = _values[region.Y + y][region.X + x]; return result; } /// /// Returns a new object which is a subregion of the grid. /// /// The X coordinate. /// The Y coordinate. /// The width. /// The height. /// The grid. public Grid Slice(int x, int y, int width, int height) { return Slice(new Rectangle(x, y, width, height)); } #endregion #region GetEnumerator /// /// Enumerates the elements of the grid. /// /// The values. public IEnumerator GetEnumerator() { for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) yield return _values[y][x]; } /// /// Enumerates the elements of the grid. /// /// The value. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion } }