単純な実装:
private static IEnumerable<T[,]> GetWindows<T>(
T[,] array,
int windowWidth,
int windowHeight)
{
for (var y = 0; y < array.GetLength(1) - windowHeight + 1; y++)
{
for (var x = 0; x < array.GetLength(0) - windowWidth + 1; x++)
{
var slice = new T[windowWidth, windowHeight];
CopyArray(array, x, y, slice, 0, 0, windowWidth, windowHeight);
yield return slice;
}
}
}
2 次元配列間でコピーするヘルパー メソッド:
private static void CopyArray<T>(
T[,] src, int srcX, int srcY,
T[,] dst, int dstX, int dstY,
int width, int height)
{
for (var x = 0; x < width; x++)
{
for (var y = 0; y < height; y++)
{
dst[dstX + x, dstY + y] = src[srcX + x, srcY + y];
}
}
}
テストメイン:
private static void Main(string[] args)
{
var array = new string[5, 5];
for (var y = 0; y < array.GetLength(1); y++)
{
for (var x = 0; x < array.GetLength(0); x++)
{
array[x, y] = string.Format("({0}|{1})", x, y);
}
}
foreach (var window in GetWindows(array, 3, 3))
{
ShowArray(window);
}
Console.ReadLine();
}
private static void ShowArray<T>(T[,] array)
{
for (var x = 0; x < array.GetLength(0); x++)
{
for (var y = 0; y < array.GetLength(1); y++)
{
Console.Write(" {0}", array[x, y]);
}
Console.WriteLine();
}
Console.WriteLine();
}
出力:
(0|0) (0|1) (0|2)
(1|0) (1|1) (1|2)
(2|0) (2|1) (2|2)
(1|0) (1|1) (1|2)
(2|0) (2|1) (2|2)
(3|0) (3|1) (3|2)
(2|0) (2|1) (2|2)
(3|0) (3|1) (3|2)
(4|0) (4|1) (4|2)
(0|1) (0|2) (0|3)
(1|1) (1|2) (1|3)
(2|1) (2|2) (2|3)
(1|1) (1|2) (1|3)
(2|1) (2|2) (2|3)
(3|1) (3|2) (3|3)
(2|1) (2|2) (2|3)
(3|1) (3|2) (3|3)
(4|1) (4|2) (4|3)
(0|2) (0|3) (0|4)
(1|2) (1|3) (1|4)
(2|2) (2|3) (2|4)
(1|2) (1|3) (1|4)
(2|2) (2|3) (2|4)
(3|2) (3|3) (3|4)
(2|2) (2|3) (2|4)
(3|2) (3|3) (3|4)
(4|2) (4|3) (4|4)
あとは、そのブログ投稿に示されているのと同じ手法を適用するだけです:)