Можно ли написать на основе правил итераторы двумерный массив структур в C # (для nieghbours плитки в сетке)? - PullRequest
0 голосов
/ 08 ноября 2019

Я использую C #, и я использовал 2d массив структур для сетки плиток. Это не о том, как найти 8 соседних плиток из плитки в сетке. Я понимаю, что в C # вы можете получить серию возвратов доходности, чтобы сделать ienumerable. Например:

public IEnumerable<int> fakeList()
{
    yield return 1;
    yield return 2;
}

И вызовите его с помощью цикла foreach. Теперь в моем классе сетки хочу иметь простой способ получить доступ к соседям в grid.array [x, y] и изменить его. Но так как это структура, я не могу написать итератор, например:

public IEnumerable<int> neighbours(int x, int y)
{
    if((x+1) >=0 && y >=0 && .....)//check if node above is inside grid
       yield return grid.array[x+1,y];
    //rinse and repeat 7 more times for each direction
}

Вместо этого, каждый раз, когда мне нужны соседи, мне нужно скопировать, вставить условия 8if и проверить, что я используюправильное направление x +, направление y +, чтобы найти действительные индексы. По сути, огромная боль.

Я мог бы обойтись:

  1. Не используя структуры и облегчая мою жизнь. И избавиться от возможной преждевременной оптимизации. НО я собираюсь запускать этот код каждый кадр в моей игре. Возможно, несколько раз. Поэтому я хотел бы сохранить структуры, если это возможно.
  2. Вместо этого напишите итератор для индексов. Пример:

Допустим ли второй подход? Или это генерирует мусор? Я не знаю, как доходность работает в деталях.

public struct GridTile
{
    public int x;
    public int z;

    public GridTile(int x, int z)
    {
        this.x = x;
        this.z = z;
    }
}




public IEnumerable<int> neighbours(int x, int y)
{
    if ((x + 1) >= 0 && y >= 0 && .....)//check if right node is inside
        yield return new Gridtile(x + 1, y);
    //rinse and repeat 7 more times for each direction
}

1 Ответ

0 голосов
/ 08 ноября 2019

Если вам известны координаты записи 2D-массива, то соседей можно получить с помощью циклов:

var twoD = new int[10,10];

var someX = 5;
var someY = 5;

List<int> neighbors = new List<int>();

for(int nx = -1; nx <= 1; nx++){
  for(int ny = -1; ny <= 1; ny++){
    int iX = someX + nX;
    int iY = someY + nY;
    if(iX > 0 && iX < twoD.GetLength(0) && iY > 0 && iY < twoD.GetLength(1))
      neighbors.Add(twoD[iX,iY]);
  }
}
...