我正在写一个Nine Men's Morris游戏,到目前为止,我有一个Negascout搜索工作得很好。但是,我想添加迭代加深,所以我提出了这个代码:
public Move GetBestMove(IBoard board, int depth)
{
//Search limits (ms
this.maxTime = 9000;
//Set initial window
int alpha = -INFINITY, beta = INFINITY;
int val = 0;
//The move that will be returned
Move bestMove = null;
//Get list of moves for the current board
List<Move> moves = board.getMoves();
//Get the time search has started
long startTime = System.nanoTime();
//Iterate through the depths
for (curDepth = 1; ; )
{
maxDepth = curDepth;
//Reset alpha
alpha = -INFINITY;
//Reset the best score position
int bestPos = -1;
//Loop through all the moves
for (int i = 0, n = moves.size(); i < n; i++)
{
//Make the move
board.make(moves.get(i), true);
//Search deeper
val = negascout(board, curDepth, alpha, beta, startTime);
//Undo the move
board.undo(moves.get(i));
//Keep best move
if (val > alpha)
{
bestMove = moves.get(i);
bestPos = i;
}
//Score missed aspiration window
if (val <= alpha || val >= beta)
{
alpha = -INFINITY;
beta = INFINITY;
//Go to next iteration
continue;
}
//Set new aspiration window
alpha = val - ASPIRATION_SIZE;
if (alpha < -INFINITY)
alpha = -INFINITY;
beta = val + ASPIRATION_SIZE;
if (beta > INFINITY)
beta = INFINITY;
}
//Move the best move to the top of the list
if (bestPos != -1)
{
moves.remove(bestPos);
moves.add(0, bestMove);
}
//Time check
double curTime = (System.nanoTime() - startTime) / 1e6;
if (curTime >= maxTime ||
val == board.getMaxScoreValue() ||
val == -board.getMaxScoreValue())
break;
//Increment current depth
curDepth++;
}
//Return the move
return bestMove;
}
我也使用了一个愿望窗口。然而,搜索返回最糟糕的举动!我认为问题在于重新/设置搜索窗口。搜索窗口应该移动到外部循环吗?
答案 0 :(得分:1)
由于你使用的是negascout,你的初始调用应该是
val = -negascout(board, curDepth - 1, -beta, -alpha, startTime);
与内部节点相比,您的根调用完全相反,因此这就解释了为什么它会返回最糟糕的移动。
答案 1 :(得分:0)
for (depth = 1;; depth++) {
val = AlphaBeta(depth, -INFINITY, INFINITY); // or negascout
if (TimedOut())
break;
}
与您使用GetBestMove
实施的内容不同。内循环(迭代可能的移动)应该是negascout
的一部分。此外,您似乎只在第一深度级别(1层)存储移动顺序,但为了使迭代加深搜索非常快,它需要在目前为止搜索的每个深度处的移动排序。迭代加深不仅具有将时间考虑在内的优点(在x秒后完成),而且还具有产生良好移动顺序的优点。并且alphabeta或negascout算法受益于良好的移动排序(首先尝试此移动,因为在先前的搜索中它是最好的)。实现移动排序的常用方法是transposition table。
来自Bruce Moreland的文件The Main Transposition Table和Iterative Deepening对我非常有帮助,我希望链接也可以帮到你!