我正在使用Java中的24位位板代表以下形式的游戏板:
00 01 02 03 04
05 06 07 08 09
10 11 XX 12 13
14 15 16 17 18
19 20 21 22 23
请注意,电路板的中间有一个孔,用'XX'表示。我已经生成了一个合法的位板列表,但由于该板具有正方形的对称性,我可以扔掉大量已经由列表中的对称表兄弟代表的位板。
为了检查这些对称性,我需要能够将板旋转90度,180度和270度以及水平,垂直和对角镜面(在两个对角线上)镜像的功能。显然我想利用位操作,但这就是我被困住的地方。我已经找到了一些关于如何为国际象棋棋盘做这个的信息,但我无法理解这个概念 - 更不用说如何将它应用到我自己的棋盘上了。
有人可以通过一些解释向我展示如何有效地旋转/镜像位板吗?
答案 0 :(得分:1)
我在这里找到了最有效方法的汇编:
http://chessprogramming.wikispaces.com/Flipping+Mirroring+and+Rotating
例如,64位板的垂直翻转只有13个操作,没有任何if语句。旋转可以通过翻转和镜像的组合来完成。
有些算法在您第一次看到它们时看起来就像魔术一样。要真正理解它们,每次操作后都有助于转储板的状态。
答案 1 :(得分:0)
我想知道你是否误解了什么。我怀疑你不会根据拓扑结构动态生成位板的旋转算法,我希望你能够硬编码旋转算法。
所以我会将旋转编码为:
00 -> 04
01 -> 09
02 -> 13
03 -> 18
04 -> 23
...
然后,您可以在一个方法/例程中对此进行编码,该方法/例程将位板作为参数,执行转换并返回结果。您可能会发现某些转换可以使用二进制逻辑运算符进行编码,但应该将其作为算法的优化而不是基本概念。
有一个使用位板here的好例子,一个知识渊博的开发人员正在讨论在跳棋游戏中使用位板。
或者,您可以选择不同的表示形式,例如:
00 10 20 30 40
01 11 21 31 41
02 12 XX 32 42
03 13 23 33 43
04 14 24 34 44
显然更简单的转换和旋转变换以及在比特使用中非常合理的权衡。
您选择的表示形式取决于您计划在游戏中进行的移动类型以及哪些移动应该易于计算。