4

我打算写一个游戏(如果你听说过它,它被称为“Qwirkle”),其中一个二维游戏场存储玩家投入的石头的位置。第一个玩家将一块石头放在任何地方,其他玩家可以从任何一侧(左/右/顶部和底部)连接到它。游戏场本身并不局限于会破坏游戏理念的固定大小。但是,棋子的数量仅限于玩家在开始时可以定义的值。

由于游戏逻辑,我需要用索引遍历石头。但是,由于玩家可以从任何一侧添加石头,我需要一个可以扩展到任何方向的列表(例如,到负和正索引方向)。

性能并不是不重要的,因为我需要一次检查几块石头。

最好的办法是访问像 _stones[-3,5] 这样的石头来访问位置 -3、5 的石头,当然。

我认为可以从任何一侧推送和弹出的堆栈(如 PushBack / PushFront)对此很有用,但我不太确定如何在 C# 中实现这一点。

是否有像我正在考虑的那样预先实现的列表/堆栈,或者我的方法完全奇怪?

4

5 回答 5

5

您想要的数据结构是不可变的四叉树。如果棋盘大部分是空的,那么使用不可变四边形可以让您表示基本上无限大小的棋盘;与 32 x 32 单元板相比,1 万亿 x 1 万亿单元板仅占用几个字节的内存。不可变四叉树可以很容易地以您描述的方式进行索引,并且在给定旧四叉树和编辑的情况下计算新四叉树很简单。

这些年来,我已经多次编写了不可变四叉树算法,并且很长一段时间以来我一直想写一系列关于它们的博客文章,但我从来没有这样做过。当我这样做时,我会回来更新这个答案。

同时,这篇 Dobbs 博士关于 Gosper 算法的文章是我用来学习不可变四叉树如何工作的文章。

http://www.drdobbs.com/jvm/an-algorithm-for-compressing-space-and-t/184406478

于 2013-03-19T16:31:26.210 回答
2

你想要的是一个双端队列(称为双端队列,发音为“deck”)。.NET BCL 中没有实现(不幸的是),但有 3rd 方实现(参见 Google)。

于 2013-03-19T15:11:31.403 回答
0

字典可能是一种选择,而不是考虑列表的索引,您可以考虑字典的整数键。不管是什么维度。

Dictionary<int,Dictionary<int,Stone>> stones = new Dictionary<int,Dictionary<int,Stone>>();
// do some initialisation for the base field size ...

// access it this way
Stone s = stones[-1][-5];

唯一的问题是当您想要添加一个会消耗资源的第二维(迭代所有第一维)时。

于 2013-03-19T15:13:10.117 回答
0

我认为您将从实现包含两个 ArrayList 的自定义数据结构中学到更多。一个前进一个后退。当然,在您的实现中,它们都将采用相同的方式,但您的实现可以让数据结构返回正索引加一的否定,这样您就不会为后向 ArrayList 中的第一个元素获得 -0 的索引.

也许我误解了这个问题,但这就是我将如何实现双向可扩展数据结构的方式。

祝你好运!

于 2013-03-20T09:21:01.790 回答
-1

您可以执行以下操作:

_stones[-(i),i] 和/或 _stones[i,-(i)]

只是一个建议。

于 2013-03-19T15:07:54.673 回答