28 个版本 (8 个稳定版)
1.5.0 | 2023年1月10日 |
---|---|
1.4.0 | 2022年12月26日 |
0.3.6 | 2022年12月21日 |
0.2.11 | 2022年12月20日 |
0.0.1 | 2022年12月7日 |
#2 in #cetkaik
用于 2 crates
5MB
1K SLoC
cetkaik_compact_representation
将机战的棋盘紧凑存储
前提
0o
开头的是八进制,0b
开头的是二进制
存储方法
首先,以下称为“棋子编号”。
棋子编号的高位2位保持以下信息。
- 高位2位为 0b00 → 两者都不能移动(空位)
- 高位2位为 0b01 → IASide 可以移动(普通棋子)
- 高位2位为 0b10 → ASide 可以移动(普通棋子)
- 高位2位为 0b11 → 两者都可以移动(皇帝)
另一方面,普通棋子的低位6位在整个游戏内是唯一的,“棋盘到手的移动”、“手从手到棋盘的移动”也不会改变低位6位。
Board
Board 是将棋子信息填充到 9x9 的二维数组中,按以下顺序排列,由 81 个字节组成,对齐为 1。
[
[KA, LA, ..., PA],
[KE, LE, ..., PE],
...
[KIA, LIA, ..., PIA]
]
初始棋盘的棋子编号分配如下所示。
[
[0o242, 0o236, 0o226, 0o252, 0o255, 0o253, 0o227, 0o237, 0o243],
[0o247, 0o223, 0o000, 0o233, 0o000, 0o232, 0o000, 0o222, 0o246],
[0o210, 0o211, 0o212, 0o213, 0o257, 0o217, 0o216, 0o215, 0o214],
[0o000, 0o000, 0o000, 0o000, 0o000, 0o000, 0o000, 0o000, 0o000],
[0o000, 0o000, 0o000, 0o000, 0o300, 0o000, 0o000, 0o000, 0o000],
[0o000, 0o000, 0o000, 0o000, 0o000, 0o000, 0o000, 0o000, 0o000],
[0o100, 0o101, 0o102, 0o103, 0o156, 0o107, 0o106, 0o105, 0o104],
[0o144, 0o120, 0o000, 0o130, 0o000, 0o131, 0o000, 0o121, 0o145],
[0o141, 0o135, 0o125, 0o151, 0o154, 0o150, 0o124, 0o134, 0o140],
]
Field
Field 是在 Board 上添加手棋信息的结果,手棋信息用 96 位(= 12 字节)的位向量表示。对齐为 1。
具体示例
上图显示了 ASide 的赤虎 (0o233)、赤弓 (0o223)、赤兵 (0o217)、赤船 (0o257)、黑虎 (0o232) 移至 IASide 的手棋,IASide 的黑兵 (0o102)、赤兵 (0o107)、黑船 (0o156)、赤巫 (0o145)、赤马 (0o135) 移至 ASide 的手棋。因此,将上图转换为位序列
[
0b00001000, /* 兵 */ 0b00000010, /* 兵 */
0b00000000, /* 兵 */ 0b00000001, /* 兵 */
0b00000001, /* 弓 */ 0b00000000, /* 車 */
0b00000101, /* 虎 */ 0b00100000, /* 馬 */
0b00000000, /* 筆 */ 0b00100000, /* 巫 */
0b00000000, /* 将 */ 0b00001001 /* 王と船 */
]
但是,unsafe { std::mem::transmute::<Hop1zuo1, [u8; 12]>(hop1zuo1) }
的结果。