Java 将移动搜索算法推广到使用递归
我正在创建一个简单的人工智能,需要评估董事会状态 根据定义的策略规则。这个游戏很像俄罗斯方块: 你需要根据董事会的状态和情况,决定当前的最佳举措 接下来N个片段的顺序(N是一个变量) 换句话说,您必须使用工件队列中的第一个工件(如俄罗斯方块中的多个) “下一个”级别) 对于向前一步,这非常简单:Java 将移动搜索算法推广到使用递归,java,algorithm,recursion,artificial-intelligence,Java,Algorithm,Recursion,Artificial Intelligence,我正在创建一个简单的人工智能,需要评估董事会状态 根据定义的策略规则。这个游戏很像俄罗斯方块: 你需要根据董事会的状态和情况,决定当前的最佳举措 接下来N个片段的顺序(N是一个变量) 换句话说,您必须使用工件队列中的第一个工件(如俄罗斯方块中的多个) “下一个”级别) 对于向前一步,这非常简单: bestMove = function(Board board, piece piece) { possibleMoves = getPossibleMoves(board, piece)
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,但欢迎使用任何语言或伪代码 这一点可以很容易地修改,以考虑到前面的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
}
bestMove=函数(板、块、整型前瞻)
{
possibleMoves=getPossibleMoves(板、件)
bestMove=null
最佳分数=-无穷大
boardCp=克隆(板)
for(移入可能的移动)
{
/*只是原始代码*/
if(前瞻性最佳分数)
{
最佳移动=移动
bestScore=临时板.score
}
boardCp=撤消移动(临时板,移动)
}
/*递归,可以更改为循环*/
否则{
tempBoard=applyMove(boardCp,move)//应用
move2=bestMove(tempBoard,piece,lookAhead-1)//潜水并获得最佳状态
boardCp=undoMove(tempBoard,move)/(1)检查它实际有多好
tempBoard=applyMove(boardCp,move2)
如果(tempBoard.score>bestScore)
{
bestMove=move2
bestScore=临时板.score
}
boardCp=undoMove(tempBoard,move2)//通常我会重构if-else路径并重用一些代码
}
}
返回最佳移动
}
如果您可以从一个函数返回2个值,那么就不需要(1)
——您需要移动和它的分数
顺便说一句,你读过关于最小-最大、阿尔法-贝塔(带修剪)算法的书吗?这可以很容易地修改,以考虑到前面的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
}
bestMove=函数(板、块、整型前瞻)
{
possibleMoves=getPossibleMoves(板、件)
bestMove=null
最佳分数=-无穷大
boardCp=克隆(板)
for(移入可能的移动)
{
/*只是原始代码*/
if(前瞻性最佳分数)
{
最佳移动=移动
bestScore=临时板.score
}
boardCp=撤消移动(临时板,移动)
}
/*递归,可以更改为循环*/
否则{
tempBoard=applyMove(boardCp,move)//应用
move2=bestMove(tempBoard,piece,lookAhead-1)//潜水并获得最佳状态
boardCp=undoMove(tempBoard,move)/(1)检查它实际有多好
tempBoard=applyMove(boardCp,move2)
如果(tempBoard.score>bestScore)
{
bestMove=move2
bestScore=临时板.score
}
boardCp=undoMove(tempBoard,move2)//通常我会重构if-else路径并重用一些代码
}
}
返回最佳移动
}
如果您可以从一个函数返回2个值,那么就不需要(1)
——您需要移动和它的分数
顺便说一句,你读过关于min-max、alfa-beta(带修剪)算法的书吗?我帮不了你,但我可以建议你这是我在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 α
函数整数极小极大值(节点,深度)
如果节点是终端节点或深度,我无法帮助您,但我可以建议您,这是我在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 α
函数整数极小极大值(节点,深度)
如果节点是终端节点或深度纯递归算法。不知道你们接下来的作品是如何组织的,所以这里我使用了一个队列来假设。但是克隆并不是最有效的,所以这取决于您的数据结构
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
}
函数getBestPossibleScore(单板,队列下一个单板){
if(nextPieces.isEmpty())
返回板。得分;
piece=piece.pop();
possibleMoves=getPossibleMoves(板、件)
最佳分数=-无穷大
boardCp=克隆(板)
for(移入可能的移动)
{
tempBoard=applyMove(boardCp,move)
currentScore=getBestPossibleScore(tempBoard,nextPieces.clone());
如果(当前分数>最佳分数)
{
最佳分数=当前分数
}
boardCp=撤消移动(临时板,移动)
}
返回板。分数+最佳分数;
}
功能getBestMove(单板、队列下一块)
{
piece=piece.pop();
possibleMoves=getPossibleMoves(板、件)
bestMove=null;
最佳分数=-无穷大
boardCp=克隆(板)
for(移入可能的移动)
{
tempBoard=applyMove(boardCp,move)
currentScore=getBestPossibleScore(tempBoard,nextPieces.clone());
如果(当前分数>最佳分数)
{
最佳分数=当前分数
最佳移动=移动;
}
boardCp=撤消移动(临时板,移动)
}
返回最佳移动
}
纯递归算法。不知道你们接下来的作品是如何组织的,所以这里我使用了一个队列来假设。但是克隆并不是最有效的,所以这取决于您的数据结构
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
}
函数getBestPossibleScore(单板,队列下一个单板){
if(nextPieces.isEmpty())
返回板。得分;
piece=piece.pop();
possibleMoves=getPossibleMoves(板、件)
最佳分数=-无穷大
博德