设计

结构体设计

  • Map: 存储地图数据.
    • 包含所有地图元素的数组.
    • 包含玩家位置, 箱子和目标位置: 方便快速读取, 否则需要遍历数组来获取相应元素的坐标.
  • Actions: 存储玩家的动作, 包括动作的类型(移动或推动), 以及方向(上下左右).
  • Level: 关卡, 包含地图和玩家动作. 可以执行或撤销动作.

Level 中与地图相关的内容分离到 Map 中, 是为了将地图数据与关卡功能分离. 许多涉及地图的操作(例如计算两个地图之间的相似度)与关卡功能无关.

Map 的数组是否应该包含玩家和箱子元素? 🤔

  • 包含:
    • 在修改玩家位置或移动箱子时, 需要同步数组中的数据. 可能引入导致数据不一致的 BUG. 但因为实现十分简单, 因此引入 BUG 的可能性不大.
    • 存在数据冗余, 但是冗余的数据量很小, 不至于造成显著的内存占用率变化.
  • 不包含: 读取时需要判断是否与玩家或任意箱子的位置相同, 如果有就追加相关元素的枚举值. 导致读取比写入有更大的开销. 取比写入开销大违反直觉, 违背了 POLA1.

综上所述, 本文倾向于在数组里包含这些元素.

Map 的数组应该是一维的还是二维的? 🤔

由于该数组是动态数组, 二维动态数组的分配与释放需要更大的开销. 而使用一维动态数组, 内存布局会更加紧凑, 且可以提供使用二维坐标读取地图内容的关联函数. 因此使用一维数组更为合适.

转换关系

flowchart LR
    A[String] -->|XSB 格式| B[Map]
    A -->|LURD 格式| C[Actions]
    C -->|重建| B
    B --> D[Level]