我正在使用minimax算法,包括tic-tac-toe,reversi等。
如何正确地向算法添加一个玩家跳过转弯的可能性(当没有有效移动时)?
01 function minimax(node, depth, maximizingPlayer)
02 if depth = 0 or node is a terminal node
03 return the heuristic value of node
04 if maximizingPlayer
05 bestValue := −∞
06 for each child of node
07 v := minimax(child, depth − 1, FALSE)
08 bestValue := max(bestValue, v)
09 return bestValue
10 else (* minimizing player *)
11 bestValue := +∞
12 for each child of node
13 v := minimax(child, depth − 1, TRUE)
14 bestValue := min(bestValue, v)
15 return bestValue
感谢。
答案 0 :(得分:1)
我为一款涉及传球的游戏实施了Minimax。因此,pass
是用户可以执行的操作。在我的情况下,在“通过”状态下,你可以做一些“重新行动”作为玩家,但这在这里是无关紧要的。
您可以将player->pass = true
添加为新状态并将其添加到树中,只要确保在任何操作添加到树之前检查该播放器是否已经通过,并跳过它。
然后,您需要处理允许他们通过的次数。从现在开始,如果所有玩家都通过,游戏可以无限期地继续下去。这取决于游戏。在我的情况下,当一个玩家通过时他们不再做任何事情(超出我之前提到的),然后当所有玩家都通过时,该轮结束并且所有通过状态都被重置。
我游戏中的一个例子:
std::list<GameState*> GameState::generateChildren(GameState& parent) {
std::list<GameState*> children;
PlayerBoard* currentBoard = parent.getCurrentPlayer();
if (!currentBoard->pass) {
GameState* childState = new GameState(parent);
PlayerBoard *childBoard = childState->getCurrentPlayer();
childBoard->pass = true;
childBoard->nextPlayer();
children.push_back(childState);
//And then all your regular actions...
}
return children;
}
答案 1 :(得分:0)
您可以编写函数GenerateValidMoves(node, player)
,该函数返回给定位置上玩家的所有有效举动的列表。然后可以将minimax例程的开始重写如下:
function minimax(node, depth, maximizingPlayer)
if depth == 0:
return heuristicValueOfNode
if generateValidMoves(node, currentPlayer) is empty:
if generateValidMoves(node, opponentPlayer) is empty:
return heuristicValueOfNode //here the game is finished since neither player can move
return minimax(node, depth, not maximizingPlayer) //call minimax for the opponent
if maximizingPlayer
bestValue := −∞
for each child of node
v := minimax(child, depth − 1, FALSE)
bestValue := max(bestValue, v)
return bestValue
else (* minimizing player *)
bestValue := +∞
for each child of node
v := minimax(child, depth − 1, TRUE)
bestValue := min(bestValue, v)
return bestValue