具有负索引的数组的实现

我正在与一个向各个方向无限延伸的世界进行游戏。 这意味着你可以在X:50Y:50X:-50Y:-50 。 但是……我不能用普通的C#List真正做到这一点……

我提出的所有想法似乎都太复杂/低效,无法工作……

实现无限网格的最简单方法是使用稀疏矩阵,其中包含x,y对作为键的字典以及要作为值存储的数据。 如果网格稀疏,这种方法快速,易于实现,并且内存友好。

另一种方式是链接网格(类似于链表,但指向4个方向),或基于区块的方法来减少链接网格的开销(区块是NxNarrays的链接网格)。 磁贴的实现非常复杂,但对于非常密集的网格,在内存和性能之间是一个很好的权衡。

但我个人最喜欢的方法是使用奇偶变换。 所以奇数指数是正数,而偶数指数是负数。 要从虚拟索引转换为物理索引,可以使用公式p = abs(v * 2) - (v > 0 ? 1 : 0)并将物理转换为虚拟索引v = (p % 2 == 1 ? +1 : -1) * ((2*p + 3) / 4) 。 之所以出现这种关系,是因为在自然数和整数(0 <-> 0), (1 <-> 1), (2 <-> -1), (3 <-> 2), (4 <-> -2), (5 <-> 3), (6 <-> -3), ...之间存在一对一和关系(双射(0 <-> 0), (1 <-> 1), (2 <-> -1), (3 <-> 2), (4 <-> -2), (5 <-> 3), (6 <-> -3), ... 这种方法快速,简单,优雅,但如果你的网格非常稀疏,并且物品距离中心线很远,那么这种方法并不是很好。

除非您有单元格的TON(是的,TON of bits …),否则您可以使用字典。 将它与System.Drawing.Point结合起来作为关键,你会得到一件好事:

 Dictionary myMap = new Dictionary(); 

编辑:除了字典之外,每个单元格都可以引用它的相邻单元格,这样你就可以使用字典直接去“某处”,然后用相邻的单元格导航。 我用这种方式在hex网格中实现A *寻路算法。

编辑2:例如,如果您想要访问特定坐标,您可以简单地

 var myTile = myMap[new Point(25, -25)]; 

然后,你想要获得East瓷砖

 var eastTile = myTile.East; 

你的网格对象也可以实现一个偏移方法,这样你就可以获得’West 2,North 5’平铺

 var otherTile = myTile.Offset(-2, 5); 

如何在两个不同的方向上使用两个List进行扩展?

我不确定这是否比您想要处理的更复杂,但您是否考虑使用极坐标而不是笛卡尔坐标? 该坐标系中没有负数。 我意识到起初的转变是困难的,但是一旦你绕过它,它就变成了第二天性。

您可以使用Dictionary,它具有数组的所有function,但显然除了负数索引。

计算机无法存储无限数组。 数组必须有一个边界,提醒您在数组初始化期间声明了特定大小的代码中的某处。 也许你在某个地方调整它的大小,但是仍然留下从0到最大的数字范围。

那么你应该做什么,写一个允许在这样的地图中相对定位的函数。 因此,您将当前地图[x,y]存储为位置。 而且你可以通过一个相对地增加/减少当前位置的function来上升。 这样可以使您的代码更易于理解。

如果你不处理游戏地图而不是数字范围,可以说你可以创建一个n点列表或二维字典。

我在这里发帖,导致你的问题可能导致人们编写错误的代码。

还可以在地图周围有边框的情况下为其他人添加(通常在游戏场景和图像处理中。数据来自[-1..width + 1],只需将其标注为[0,width + 2]然后循环开始’for(int x = 1; x