我正在创建一个需要评估电路板状态的简单AI 根据定义的政策规则。这个游戏很像俄罗斯方块: 鉴于董事会成员和国家,你需要决定最佳的当前举措 N个下一个部分的序列(N是变量)。
换句话说,你必须使用片段队列中的第一个片段(就像Tetris有多个片段一样) '下一级'。)
对于提前一步,这非常简单:
bestMove = function(Board board, piece piece)
{
possibleMoves = getPossibleMoves(board, piece)
bestMove = null
bestScore = -INFINITY
boardCp = clone(board)
for (move in possibleMoves)
{
tempBoard = applyMove(boardCp, move)
if (tempBoard.score > bestScore)
{
bestMove = move
bestScore = tempBoard.score
}
boardCp = undoMove(tempBoard, move)
}
return move
}
现在,我如何将此算法推广到N向前移动? 我不是递归专家,所以感谢您的帮助!
PS:我正在使用Java,但欢迎使用任何语言或伪代码!
答案 0 :(得分:4)
这可以很容易地修改,以便将N的进度考虑在内。无论是以递归还是迭代的方式。
bestMove = function(Board board, piece piece, int lookAhead)
{
possibleMoves = getPossibleMoves(board, piece)
bestMove = null
bestScore = -INFINITY
boardCp = clone(board)
for (move in possibleMoves)
{
/* just the original code */
if(lookAhead <= 1) {
tempBoard = applyMove(boardCp, move)
if (tempBoard.score > bestScore)
{
bestMove = move
bestScore = tempBoard.score
}
boardCp = undoMove(tempBoard, move)
}
/* recursion, can be changed to a loop */
else {
tempBoard = applyMove(boardCp, move) // apply
move2 = bestMove(tempBoard, piece, lookAhead-1) // dive and get best
boardCp = undoMove(tempBoard, move) // (1) check how good it actually is
tempBoard = applyMove(boardCp, move2)
if (tempBoard.score > bestScore)
{
bestMove = move2
bestScore = tempBoard.score
}
boardCp = undoMove(tempBoard, move2) // generaly I'd refactor both if-else paths and reuse some code
}
}
return bestMove
}
如果你可以从一个函数中返回2个值,那么就不需要(1)
- 你需要移动它的分数。
顺便说一句。您是否阅读过min-max,alfa-beta(带修剪)算法?
答案 1 :(得分:1)
function getBestPossibleScore(Board board, Queue<piece>nextPieces){
if (nextPieces.isEmpty())
return board.score;
piece = piece.pop();
possibleMoves = getPossibleMoves(board, piece)
bestScore = -INFINITY
boardCp = clone(board)
for (move in possibleMoves)
{
tempBoard = applyMove(boardCp, move)
curentScore = getBestPossibleScore(tempBoard,nextPieces.clone());
if (currentScore > bestScore)
{
bestScore = currentScore
}
boardCp = undoMove(tempBoard, move)
}
return board.score+bestScore;
}
function getBestMove(Board board, Queue<piece> nextPieces)
{
piece = piece.pop();
possibleMoves = getPossibleMoves(board, piece)
bestMove=null;
bestScore = -INFINITY
boardCp = clone(board)
for (move in possibleMoves)
{
tempBoard = applyMove(boardCp, move)
currentScore = getBestPossibleScore(tempBoard,nextPieces.clone());
if (currentScore > bestScore)
{
bestScore = currentScore
bestMove=move;
}
boardCp = undoMove(tempBoard, move)
}
return bestMove
}
答案 2 :(得分:0)
我无法帮助你,但我可以向你建议MinMax algorithm这就是我在AI大学课程中使用过的。
伪代码,如果有用:
function integer minimax(node, depth)
if node is a terminal node or depth <= 0:
return the heuristic value of node
α = -∞
for child in node: # evaluation is identical for both players
α = max(α, -minimax(child, depth-1))
return α
这个算法资产让对手做出最好的动作(基于评估函数)
答案 3 :(得分:0)
采用伪代码方法。我的第一选择始终是minimax w / alpha beta修剪,因为它是解决类似问题的常见且经过验证的方法。
但是如果你想做一些不同的事情。
List moves = new list()
Best board = current board
While (queue is not empty){
grab the next item in the queue.
Implement your algorithm.
add the move to the move list.
update the best board
}
不是最好但非常简单的方法,然后为您提供基于队列的移动列表。您只需将电路板状态从先前最佳电路板转移到算法板元素,将下一部分从队列转移到算法的片段参数中。