简体   繁体   English

是否可以在 C# 中编写基于规则的迭代器结构的二维数组(对于网格中的瓦片的邻居)?

[英]Is it possible to write rule based iterators a 2d array of structs in C#(for nieghbours of a tile in a grid)?

I'm using C# and I used a 2d array of structs for a grid of tiles.This is not about how to find 8 neighboring tiles from a tile in the grid.我正在使用 C# 并且我使用二维结构数组作为瓷砖网格。这不是关于如何从网格中的瓷砖中找到 8 个相邻的瓷砖。 I understand that in c# you can have a series of yield returns make a ienumerable.据我了解,在 c# 中,您可以让一系列收益回报成为可枚举的。 Like:喜欢:

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

And call it with a foreach loop.并用 foreach 循环调用它。 Now, in my grid class want to have an easy way to access neighbours in grid.array[x,y] and modify it.现在,在我的网格中 class 想要一种简单的方法来访问 grid.array[x,y] 中的邻居并对其进行修改。 But since it is a struct, I can't write an iterator like:但由于它是一个结构,我不能写一个迭代器,如:

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
}

Instead, every time I need the neighbors, I need to copy paste the 8if conditions and check that I'm using the correct x+direction,y+direction to find valid indices.相反,每次我需要邻居时,我都需要复制粘贴 8if 条件并检查我是否使用正确的 x+direction,y+direction 来查找有效索引。 Basically, a huge pain.基本上,巨大的痛苦。

I could work around by:我可以通过以下方式解决:

  1. Not using structs and making my life easier.不使用结构,让我的生活更轻松。 And getting rid of possible premature optimization.并摆脱可能的过早优化。 BUT I'm going to running this code every frame in my game.但是我将在我的游戏中的每一帧都运行这段代码。 Possibly multiple times.可能多次。 So I'd like to keep the structs if possible.所以如果可能的话,我想保留这些结构。
  2. Write iterator for indices instead.改为为索引编写迭代器。 Ex:前任:

Is the 2nd approach valid?第二种方法有效吗? Or does it generate garbage?还是会产生垃圾? I don't know how yield return works in detail.我不知道收益回报是如何详细工作的。

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
}

If you know the coordinates of a 2D array entry, then the neighbors can be retrieved using loops:如果您知道二维数组条目的坐标,则可以使用循环检索邻居:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM