我正在为一个类似象棋的游戏编写人工智能。
板为10x10,每侧15块
都有类似的棋步。
游戏中的一切都是按物体组织的。
tile[][]tiles;10x10,每个tile都有一个指向一个片段或空的片段指针。
到目前为止,我已经实现了一个没有修剪的minmax算法。
每轮可能的移动平均是国际象棋的两倍。
这个算法有效,但速度很慢。平均来说它可以检查
每秒40000次移动所以当深度为4时,我的游戏大约需要4-5秒
计算所有可能的移动。我稍后会实施修剪,但可能需要
先反馈一下我的执行情况。
问题:
我需要转换成char数组/位板还是类似的来加速
算计还是我做错了什么?
实现:(sudo)
为了避免很多双for循环,我会跟踪我的作品和对立面
在瓷砖列表中董事会评估也只进行一次,然后只进行更新
只有通过增减移动的值才能更新。
在minmax算法的实现中,我使用了一个gamestate类
保持当前游戏状态。
GameState {
Tile[][] board
List<Tile> myPieces;
List<Tile> otherPieces;
int[][] evaluatedBoard
int evaluatedValue
Piece moveFrom, moveTo //used to save pointer when applying move
int moveFromValue, moveToValue //used to save evaluationValue when applying move
void applyMove(Tile from, Tile to)
void undoMove(Tile from, Tile to)
GameState createCopy()
}
applyMove只更新evaluatedValue,不执行
整个array.mypieces和其他pieces也通过apply/undo更新。
最小值:
maxMove(GameState state, int depth) {
for(Tile from : state.getMyPieces().clone()) { //list will be changed
for(Tile to : from.getPiece().getPossibleMoves()) {
if(depth == 0)
//find best move and so forth
else {
state.applyMove(from, to);
minMove(state.createCopy(), depth - 1) //similar to maxMove except it uses otherPieces
state.undoMove(from, to)
}
}
}
//return best move
}
编辑:
添加了有关applymove和profiler的信息
Profiler: instructions
applyMove() 3200ms 11 430 000
undoMove() 1800ms 11 430 000
evaluateTile() 1400ms 22 400 000
minMove() 1700ms 315 493
applymove和undomove只将存储/反转指针移动到旧指针
值from和to,并用新的from替换它们
移动。然后调用EvaluateTime,它返回一个从1到10的数字
取决于片段中的枚举类型。
最佳答案
你选择的表现会让你付出巨大的代价——你考虑的每一步都需要你复制很多的状态。在我看来,你有两个选择:
(1)使您的状态表示非常小(在国际象棋中,您可以用64 x 4位或.net中的4 int64s来表示),因此复制非常便宜;或者
(2)使用delta使状态表示不可变,因此创建更新的状态是廉价的。
我先试试(1)选项,看看你怎么样。
以下是一些您可能会发现有用的链接:
http://en.wikipedia.org/wiki/Board_representation_(chess)
http://www.cis.uab.edu/hyatt/boardrep.html