【问题标题】:C++ implementation of game tree游戏树的C++实现
【发布时间】:2012-02-24 15:12:18
【问题描述】:

我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树形结构(因为在每个深度我们都有几个可能的移动)。

这是一个好方法吗?

struct TreeElement{
  SomeMoveType move;
  TreeElement *parent;
  std::vector<TreeElement*> children;
};

如何高效地将此类数据存储在文件中?有没有办法确保整个树结构将存储在内存的同一部分,这将允许使用 mmap 功能?

【问题讨论】:

  • 如果不以某种方式对其进行序列化,就无法将该结构保存到文件中,因为它包含指针并使用vector
  • 这是三个非常广泛且非常不同的问题,合而为一。请不要那样做。
  • 我会尝试命名节点(仅使用指针值)并在深度优先顺序搜索中遍历树,这样您可以生成有序的一维数组,例如:[{node:1 ,move:..,parent:0},{node:2,move:..,parent:1},{node:3,move:..,parent:2},{node:4,move:.. ,父:3}]

标签: c++ tree


【解决方案1】:

要将数据存储在同一段内存中,您可能希望为您使用的std::vector&lt;TreeElement *&gt; 提供一个分配器对象,并从您的块中分配。

为了能够序列化它,而不是存储实际的指针,您可以考虑在块中存储偏移量。然后当你读回数据时,你可以将块开始的地址添加到每个偏移量中,将其转回地址。

根据您使用的操作系统/编译器,可能已经对此提供了一些支持。例如,Microsoft 的编译器支持__based 指针,这与我所描述的差不多:一个基地址,每个基于该地址的指针实际上只是一个偏移量,而不是一个完整的指针。 mmap 的提及表明您可能无法直接使用它,但可能您正在使用的编译器/操作系统有类似的东西。否则,您可能不得不自己完成这项工作(例如,使用 based_pointer 类)。

真正的问题是您为什么要尝试序列化移动树。在典型情况下,您最好只保存当前的棋盘位置(或大约相当于移动历史)并在需要时/如果需要重新生成移动树。它足够小,非常容易存储。

【讨论】:

    【解决方案2】:

    我认为使用 std::vector 不是创建树的最佳方法,单链表样式树构造可能更简单且最好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-11
      • 2021-02-28
      • 1970-01-01
      • 2012-02-28
      相关资源
      最近更新 更多