最高效的国际象棋棋盘表示方法

6

我有一个用Java编写的象棋程序。目前我正在使用一个二维字符数组来表示棋盘,大写字母代表白色,小写字母代表黑色。我是否应该使用字节数组来减少内存使用?或者也许是枚举?谢谢。


3
只有64个单元格,真的_不需要_在意内存使用。我会创建一个类的二维数组,例如ChessBoardCell[][] - Alex Shesterov
如果你真的想节省内存,你可以将棋子的位置存储在2x3位中,将棋子本身存储在4位中(1位用于颜色,3位用于棋子)。这样,你只需要一个32 * 10 = 320位或10字节的缓冲区。你可能可以找到另一种方法来获取另一个位。但是,老实说,如果你担心将棋盘存储到64个字符中,你应该从Java切换到其他语言,如C甚至更低级别的语言。但是在它成为问题之前,你不应该担心这个问题,也就是说,在你想要存储数百万或数十亿个棋盘之前。 - GolezTrol
感谢您的所有评论。我的国际象棋程序具有撤销功能,每次进行移动时都会将2D数组添加到数组列表中。 - user3193535
@Alex Shesterov,国际象棋引擎的强度实际上取决于移动生成器的执行速度。使用类是你可能犯的最严重的错误,因为它太慢了。 - xXliolauXx
@ xXliolauXx,我完全不同意;如果使用花哨的方式表示单元格并将其他信息(如尝试的移动等)存储在其他地方,则存储和检索有关单元格的其他信息的逻辑可能需要更多时间。此外,如果极高的效率很重要,并且涉及CPU时钟周期,则Java也不是正确的语言。 - Alex Shesterov
@Alex,不要无礼,你写过国际象棋引擎吗?除了 UI 外,没有必要使用任何“花哨的信息”,我同意 UI 需要类。然而,整个后台工作应该在不使用类的情况下完成。我同意 Java 不是所有语言中最快的,但只要不犯使用类的错误,它就足够快了。 - xXliolauXx
1个回答

7
简而言之:使用位棋盘是最高效和专业的方法。
基本上,有三种经常使用的国际象棋棋盘表示方法:
  • 8x8 二维数组: 速度较慢但易于维护

  • 10x12 一维数组: 更快,但有点棘手

  • 位棋盘: 它们是最快的方法,也被专业引擎如Stockfish或Rybka所使用。基本上,您需要一个64位无符号整数来表示每个棋子类型,其中每个比特代表单个格子。有关更多信息,我建议参考chessprogramming wiki或google=>bitboards。


那我必须在一个单一的类中编写所有检查合法移动的代码吗?没有面向对象编程吗? - user3193535
2
基本上是的。我仍然建议创建一个类或结构体棋盘,以便将位棋盘清晰地保持在一起。并尽可能使用静态方法和类,这会产生另一个性能提升。 - xXliolauXx
@xXliolauXx 你忽略了一个非常重要的细节,即特定棋子的位棋盘不能表示哪些棋子是黑色的,哪些是白色的。为此,您需要另一个位棋盘。因此,总共有六个位棋盘:兵、马、象、车、后和派系。每个玩家只能有一个国王,因此不需要额外的位棋盘。从那里开始,您可以使用每个玩家一个字节来表示国王的位置(1,64)。为了节省一个额外的字节,您还可以将两个派系的国王放入单个字节中,其中较低位/较高位表示两个国王的位置。 - Hatefiend
@Hatefiend 如果我误解了你的评论,我提前向你道歉。首先,为什么你认为这是一个非常重要的细节?其次,它取决于你对图形类型的定义是否已经包括颜色。第三,是的,在节省空间方面,你提出的所有建议都是正确的,但在国际象棋引擎中,这并不重要。位棋盘的优势不在于存储空间,而在于能够将移动生成器实现为位操作,这是运行时最耗时的部分。存储只是查找表的问题,但你只在那里存储哈希值。 - xXliolauXx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接