// Copyright (c) 2026 GeWuYou // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. namespace GFramework.Core.Extensions; /// /// 数组扩展方法类,提供二维数组的边界检查等实用功能。 /// public static class ArrayExtensions { /// /// 检查二维数组的给定坐标是否在有效边界内。 /// /// 数组元素类型。 /// 要检查的二维数组。 /// 要检查的 X 坐标(第一维索引)。 /// 要检查的 Y 坐标(第二维索引)。 /// 如果坐标在数组边界内则返回 true;否则返回 false。 public static bool IsInBounds(this T[,] array, int x, int y) { return x >= 0 && y >= 0 && x < array.GetLength(0) && y < array.GetLength(1); } /// /// 获取二维数组指定位置的元素,如果越界则返回默认值。 /// /// 数组元素类型。 /// 要访问的二维数组。 /// X 坐标(第一维索引)。 /// Y 坐标(第二维索引)。 /// 如果在边界内返回该位置的元素;否则返回类型的默认值。 public static T? GetOrDefault(this T[,] array, int x, int y) { return array.IsInBounds(x, y) ? array[x, y] : default; } /// /// 获取二维数组指定位置的元素,如果越界则返回指定的回退值。 /// /// 数组元素类型。 /// 要访问的二维数组。 /// X 坐标(第一维索引)。 /// Y 坐标(第二维索引)。 /// 当坐标越界时返回的回退值。 /// 如果在边界内返回该位置的元素;否则返回指定的回退值。 public static T GetOr(this T[,] array, int x, int y, T fallback) { return array.IsInBounds(x, y) ? array[x, y] : fallback; } /// /// 尝试获取二维数组指定位置的元素。 /// /// 数组元素类型。 /// 要访问的二维数组。 /// X 坐标(第一维索引)。 /// Y 坐标(第二维索引)。 /// 输出参数,用于存储获取到的元素值。 /// 如果成功获取元素则返回 true;否则返回 false。 public static bool TryGet(this T[,] array, int x, int y, out T value) { if (array.IsInBounds(x, y)) { value = array[x, y]; return true; } value = default!; return false; } /// /// 获取二维数组中某个位置的四个方向邻居坐标(上、下、左、右)。 /// /// 数组元素类型。 /// 源二维数组。 /// 中心位置的 X 坐标。 /// 中心位置的 Y 坐标。 /// 按顺序返回所有在边界内的邻居坐标。 public static IEnumerable<(int x, int y)> GetNeighbors4(this T[,] array, int x, int y) { var dirs = new (int dx, int dy)[] { (0, -1), (0, 1), (-1, 0), (1, 0) }; foreach (var (dx, dy) in dirs) { var nx = x + dx; var ny = y + dy; if (array.IsInBounds(nx, ny)) yield return (nx, ny); } } /// /// 获取二维数组中某个位置的八个方向邻居坐标(包括对角线)。 /// /// 数组元素类型。 /// 源二维数组。 /// 中心位置的 X 坐标。 /// 中心位置的 Y 坐标。 /// 按顺序返回所有在边界内的邻居坐标(不包括中心位置)。 public static IEnumerable<(int x, int y)> GetNeighbors8(this T[,] array, int x, int y) { for (var dx = -1; dx <= 1; dx++) { for (var dy = -1; dy <= 1; dy++) { if (dx == 0 && dy == 0) continue; var nx = x + dx; var ny = y + dy; if (array.IsInBounds(nx, ny)) yield return (nx, ny); } } } /// /// 枚举二维数组中的所有元素及其坐标。 /// /// 数组元素类型。 /// 要枚举的二维数组。 /// 依次返回每个元素的坐标和值的元组。 public static IEnumerable<(int x, int y, T value)> Enumerate(this T[,] array) { for (var x = 0; x < array.GetLength(0); x++) { for (var y = 0; y < array.GetLength(1); y++) { yield return (x, y, array[x, y]); } } } /// /// 获取二维数组的宽度(第一维长度)。 /// /// 数组元素类型。 /// 要获取宽度的二维数组。 /// 数组的第一维长度。 public static int Width(this T[,] array) => array.GetLength(0); /// /// 获取二维数组的高度(第二维长度)。 /// /// 数组元素类型。 /// 要获取高度的二维数组。 /// 数组的第二维长度。 public static int Height(this T[,] array) => array.GetLength(1); }