我正在用Java编写一个国际象棋引擎,并使用位板来表示棋盘(12位数字)。根据IntelliJ调试器,该类实例的大小(其保留大小)为152字节。当我试图看到一些移动时,我认为我为每个移动创建一个新的实例来代表新的棋盘状态。下面是Board类的大致样子。
public long WP=0L, WN=0L, WB=0L, WR=0L, WQ=0L, WK=0L, BP=0L, BN=0L, BB=0L, BR=0L, BQ=0L, BK=0L;
long NOT_WHITE_PIECES;
long WHITE_PIECES;
long BLACK_PIECES;
long OCCUPIED;
long EMPTY;
public void updateBitboards() {}
public void updateMailbox() {}
public void movePiece(Move move) {}
public void drawBitboard() {}
其他字段和方法是静态的,所以我认为它们不会影响实例的大小。问题是,即使我只想考虑国际象棋的前4步,也有大约800万种可能的组合。所以我最终将存储总共8,000,000*152B = 1,216,000,000B…1.2GB
我觉得我在这里错过了什么。我如何增加一次考虑的职位数量?
首先,您不希望每次移动都创建一个新的棋盘状态实例。如果你正在使用例如Minimax,那么你进行移动,进行递归调用,然后取消移动。这样,它总是只考虑一个板状态。
然后为了最小化你需要考虑的移动次数你想要对算法进行改进。最常见的开始是α - β修剪,你可以在这里阅读更多信息:https://www.chessprogramming.org/Alpha-Beta。α - β剪枝总是会得到和极大极小相同的结果,但是你考虑的位置更少,因为你没有搜索无望的位置。
还有很多其他的修剪技术可以用来减少搜索树。其中大多数不会产生相同的结果,因为您"手动"操作。选择切断某些你"认为"的职位。会很糟糕。这可能是这样的假设:做某事总比什么都不做要好(null移动修剪)。
你可以做其他简单的事情来加速算法是看移动排序。为了使极大极小法最有效,你总是希望在每个位置首先看到最佳的移动。这样你就可以得到更多的截止点,而不用搜索那么多的移动。你需要知道的关于国际象棋编程的一切都可以在https://www.chessprogramming.org/找到。