我一直在尝试实现一个minMax算法(稍后会尝试使用alphabeta修剪)进行一个简单的游戏....我已经看过很多伪代码和教程,但我无法让它工作......
一点帮助将不胜感激:)
以下是相关的类...(为清晰起见,删除了实现)
class Board { //Stores board state, Immutable
Board playMove(Move m); //generates new Board after playing "Move m"
List<Move> nextMoves(Move m); // generates all possible moves, previous move is required to decide the validity of the next moves
boolean isTerminal(); //board at terminal state?
}
class Move { //stores positions played and score gained from that move
}
这是我的Min-Max实施......有人可以指出我做错了吗?谢谢。
private Move bestMove = null; // field variable
private int maxMove(Board board, Move prevMove, int myScore, int oppnScore) {
out("maxMove " + board );
if(board.isTerminal()) {
return myScore - oppnScore;
}
int mx = Integer.MIN_VALUE;
for(Move nxtMove: board.nextMoves(prevMove)) {
int k = minMove(board.playMove(nxtMove),
nxtMove,
myScore + nxtMove.score,
oppnScore);
if(k > mx) {
mx = k;
bestMove = nxtMove;
}
}
return mx;
}
private int minMove(Board board, Move prevMove, int myScore, int oppnScore) {
if(board.isTerminal()) {
return myScore - oppnScore;
}
out("minMove " + board );
int mn = Integer.MAX_VALUE;
for(Move nxtMove: board.nextMoves(prevMove)) {
int k = maxMove(board.playMove(nxtMove),
nxtMove,
myScore,
oppnScore + nxtMove.score);
if(k < mn) {
mn = k;
bestMove = nxtMove;
}
}
return mn;
}
编辑:游戏的简要描述如下,你有一定数量的不同面额的硬币。您和另一名玩家轮流从eithor侧(左侧或右侧)移除一枚硬币。硬币的面额表示您为该移动得分。某些硬币具有特殊含义,比如说拾取X意味着你会跳过一个转弯,或者Y意味着你将再转一圈。你的目标是获得比你的对手更多的分数。
答案 0 :(得分:0)
我只看到一个错误:你不记得你为给定的电路板状态选择了哪个转弯因此你计算了很多次并且算法变慢了。或速度不是你的问题?
答案 1 :(得分:0)
我认为我不清楚游戏规则,但看起来你的终端状况并不完全正确。
您将返回玩家之间得分的差异。这意味着一个玩家想要最大化这个值(与对手的最大差异),而另一个想要最小化这个(他试图将最接近的可能得分作为对手)。这真的不像任何真正的游戏所具有的目标。
我认为你想要的是得分最高的玩家获胜。因此,您只需检查myScore&gt; oppScore是否相应地返回1,0和-1。这意味着第一个玩家希望最大化回报(即他试图使其成为1 - 他赢了),而对手试图最小化回报(即如果它是-1则他获胜)。如果没有获胜,他们宁愿选择0(平局)。
另外,为什么需要prevMove
来产生下一步行动? board
不具备有关当前游戏状态的所有信息(即剩下的硬币)吗?