C ++ minimax函数

时间:2010-09-02 19:49:59

标签: c++ algorithm minimax

我已经在Google和Stackoverflow上搜索了这个问题,但我仍然不明白minimax函数是如何工作的。

我发现维基百科条目有函数的伪代码版本:

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 α

我在Google上发现的其他几个minimax函数基本上都是一样的;我正在尝试用C ++实现这个,这是我到目前为止所提出的:

double miniMax(Board eval, int iterations)
{
    //I evaluate the board from both players' point of view and subtract the difference
    if(iterations == 0)
        return boardEval(eval, playerNumber) - boardEval(eval, opponentSide());

    /*Here, playerTurn tells the findPossibleMoves function whose turn it is;
    I mean, how do you generate a list of possible moves if you don't even know
    whose turn it's supposed to be? But the problem is, I don't see where I can
    get playerTurn from, as there are only 2 parameters in all the examples of
    minimax I've seen*/
    vector<int> moves = eval.findPossibleMoves(playerTurn);

    //I'm assuming -∞ in the wikipedia article means a very low number?
    int result = -999999999;

    //Now I run this loop to evaluate each possible move
    /*Also, the Lua example in the wiki article has
      alpha = node.player==1 and math.max(alpha,score) or math.min(alpha,score)
      Is alpha a boolean there?!*/
    for(int i = 0; i * 2 < moves.size(); i++)
    {
        //I make a copy of the board...
        Board temp = eval;

        /*and make the next possible move... once again playerTurn crops up, and I
        don't know where I can get that variable from*/
        temp.putPiece(moves[i * 2], moves[i * 2 + 1], playerTurn);

        /*So do I create a function max that returns the bigger of two doubles?*/
        result = max(result, -miniMax(temp, iterations - 1));
    }

    return result;
    /*So now I've returned the maximum score from all possible moves within a certain
    # of moves; so how do I know which move to make? I have the score; how do I know
    which sequence of moves that score belongs to?*/
}

正如你所看到的,我对这个极小极大功能感到很困惑。请至少给我一些提示来帮助我。

谢谢! :)

5 个答案:

答案 0 :(得分:2)

来自维基百科的样本正在使用Alpha / Beta修剪进行NegaMax

直接命名可能会对你有所帮助:

  • 基础是MiniMax,文字实现将涉及2个轮流(相互递归)的方法,每边1个。

  • 懒惰的程序员将其转换为NegaMax,这是一种策略性放置-运算符的方法。

  • Alpha / Beta修剪跟踪最佳移动窗口(多个深度)以检测死枝。

您的playerTurn用于确定轮到谁。在NegaMax中,您可以从奇数或偶数的深度(迭代)得出这个。但是使用2个参数(myColor,otherColor)会更容易,并在每个级别切换它们。

答案 1 :(得分:1)

你的miniMax()函数应该记住它到目前为止发现的最佳动作。所以代替这段代码:


  /*So do I create a function max that returns the bigger of two doubles?*/
  result = max(result, -miniMax(temp, iterations - 1));

你应该这样做:


  /*So do I create a function max that returns the bigger of two doubles?*/
  double score = -miniMax(temp, iterations - 1);
  if (score > result)
  {
     result = score;
     bestMove = i;
  }

当然,您需要一个变量“bestMove”以及一种将最佳移动返回给调用者的方法。

答案 2 :(得分:1)

playerTurn变量作为参数添加到miniMax,并调用当前玩家最初和递归移动的miniMax

此外,opponentSide必须是playerTurn的函数。

答案 3 :(得分:1)

从游戏树搜索开始的好地方是chess programming wiki。关于此举的问题:我认为最常见的是有两个最大功能。两个最大函数之间的区别在于,一个仅返回分数,另一个返回分数和最佳移动。递归调用顺序如下:

maxWithBestMoveReturn(...) --> min(...) --> max(...) --> min(...)

有一些关于Alpha Beta算法的伪代码的好文章:

评论中的问题:和math.max(alpha,score)或math.min(alpha,score)alpha是布尔值吗?!

没有alpha是alpha beta算法中绑定的窗口。 alpha值将使用新值更新。因为alpha和beta与negamax-Function的递归调用交换,alpha变量指的是下一个递归调用中的beta变量。

对playerTurn变量的一个注意事项:minimax或alpha-beta算法不需要此信息。所以我会将信息 - 谁是下一个 - 提供给董事会结构。函数findPossibleMoves和boardEval从Board-Structure获取所需的所有信息。

递归中断条件的一个注释:如果我理解你的代码是正确的,那么你只有iterations == o的代码。我认为这意味着算法已达到所需的深度。但是,如果算法没有可能的移动,那么算法达到了这个深度。也许你应该写下面的内容:

vector<int> moves = findPossibleMoves(...);
if (!moves.size())
    return boardEval(...);

答案 4 :(得分:0)

在您的伪代码中,节点变量必须包含有关当前电路板位置(或其他)的所有信息。这些信息将包括轮到谁移动。