国际象棋AI:基于对象的MinMax实现

我正在为一个类似于国际象棋的游戏编写AI。这个棋盘是10×10的,每一方有15个棋子,这些棋子的移动方式类似于国际象棋的棋子。

游戏中的所有元素都以对象的形式组织。Tile[][] tiles; 10×10,每个Tile都有一个指向棋子的指针,或者是null。

到目前为止,我已经实现了一个没有剪枝的MinMax算法。每轮可能的移动平均是国际象棋游戏的两倍。

算法可以工作,但速度非常慢。平均每秒可以检查40000个移动/秒。因此,在深度为4的情况下,我的游戏需要大约4-5秒来计算所有可能的移动。我稍后会实现剪枝,但首先需要对我的实现进行一些反馈。

问题:我是否需要转换为字符数组/位板或类似的方法来加速计算,或者我做错了什么?

实现:(伪代码)为了避免大量的双重for循环,我通过Tiles的列表来跟踪myPieces和opponentPieces。棋盘评估也只进行一次,然后只通过添加和减去移动的值来更新。在我的MinMax算法实现中,我使用了一个GameState类来保存当前的游戏状态。

GameState { Tile[][] board List<Tile> myPieces; List<Tile> otherPieces; int[][] evaluatedBoard int evaluatedValue Piece moveFrom, moveTo //用于在应用移动时保存指针 int moveFromValue, moveToValue //用于在应用移动时保存评估值 void applyMove(Tile from, Tile to) void undoMove(Tile from, Tile to) GameState createCopy()}

ApplyMove只更新evaluatedValue,而不遍历整个数组。myPieces和otherPieces也通过apply/undo进行更新。

MinMax:

maxMove(GameState state, int depth) { for(Tile from : state.getMyPieces().clone()) { //列表将被更改   for(Tile to : from.getPiece().getPossibleMoves()) {       if(depth == 0)         //找到最佳移动等       else {        state.applyMove(from, to);        minMove(state.createCopy(), depth - 1) //与maxMove类似,但使用otherPieces        state.undoMove(from, to)       }   } } //返回最佳移动}

编辑:添加了关于applyMove和Profiler的信息

Profiler:          instructionsapplyMove()     3200ms  11 430 000 undoMove()      1800ms  11 430 000evaluateTile()  1400ms  22 400 000minMove()       1700ms  315 493 

applyMove和undoMove只存储/恢复从和到旧值的指针,并用移动的新值替换它们。然后调用evaluateTile,它根据棋子中的枚举类型返回1-10之间的数字。


回答:

你的表示选择将花费你很多成本——你考虑的每一个移动都需要复制大量的状态。我认为你有两个选择:

(1) 使你的状态表示非常小(在国际象棋中,你可以用64 x 4位,或者在.NET中用4个Int64来实现),这样复制它就非常便宜;或者

(2) 使你的状态表示为不可变的增量状态,这样创建更新的状态就很便宜。

我会先尝试选项(1),看看效果如何。

你可能会发现以下链接有用: http://en.wikipedia.org/wiki/Board_representation_(chess)http://www.cis.uab.edu/hyatt/boardrep.html

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注