QT五子棋项目详解之五:AI人机对战Alpha-Beta剪枝算法

前面介绍了单纯的max-min算法,其效率是很低的,只能思考四层。没有看过的,先去看看,才能理解后面的。

只能思考4层是由于可能的走法太多了,如第一步电脑有225种走法,每一种走法都会导致玩家有224种走法............就像是一颗庞大的树。由于可能性太多,所以优化是必须的。优化的第一种办法就是剪枝。

没有看过的,先去看看,才能理解后面的。

QT五子棋项目详解之四:AI人机对战max-min极大极小值博弈算法:

http://blog.****.net/weixin_39788534/article/details/79499966


我接着前面的讲,如下图,思考两层的情况:计算的顺序是这样的:

先遍历了A分支的D,E,又遍历其他分支。F,G.........

QT五子棋项目详解之五:AI人机对战Alpha-Beta剪枝算法

我们可以考虑一下下面的这种情况:即当计算到H的时候,我已经没有必要去计算C节点的其他分支I....了

为什么,你想一下,当电脑走了C节点后,玩家会选择一个对玩家最不利的点,如果I的值大于1,那玩家就会选择1.

如果I的值等于0,那玩家就会选择0这个点,导致C的分数变成了0.不管I的值是什么,玩家都会选择前面的3这个节点,这样就大大的提高了效率。

因此,对于剪枝需要保留这一层的最值,对于电脑这一层来说,就是需要保留最大的3,如果后面的节点如C的节点比3小就不用再判断了。

就像是模拟人的思考方式一下,真的很简单。一切都是合理的方式。

代码也很简单,多加了几行。:


QPoint Game::maxmin2(int deep)
{
    int best = INT_MIN;
   QVector<QPoint> points =  gen(deep,computerColor);
   for(int i = 0;i<points.count();i++)
   {
       chess[points[i].x()][points[i].y()] = computerColor;
            int v = min2(deep-1,best > INT_MIN ? best : INT_MIN,INT_MAX,points[i]);
            if(v==best)
            {
                bestpoints.push_back(points[i]);
            }
            if(v>best)
            {
                best = v;
                bestpoints.clear();
                bestpoints.push_back(points[i]);
            }
        chess[points[i].x()][points[i].y()] = 0;
   }
    srand((unsigned)time(NULL));
    points.clear();
   return bestpoints[rand()%bestpoints.count()];
}

int  Game::max2(int deep,int alpha, int beta,QPoint point)
{
    if(deep <= 0 || ifWin(point.x(),point.y()))
    {
        int k =evalute();
        return k;
    }
    int best = INT_MIN;

    QVector<QPoint> points = gen(deep,computerColor);
    for(int i = 0;i<points.count();i++)
    {
        chess[points[i].x()][points[i].y()] = computerColor;
             int v = min2(deep-1,best > alpha ? best : alpha, beta,points[i]);
             if(v>best)
             {
                 best = v;
             }
             chess[points[i].x()][points[i].y()] = 0;
             if(v >beta)
             {
                break;
             }
        }
    points.clear();
        return best;
    }
int  Game::min2(int deep,int alpha, int beta,QPoint point)
{
    if(deep <= 0 || ifWin(point.x(),point.y()))
    {
        int k =evalute();
        return k;
    }
    int best = INT_MAX;

    QVector<QPoint> points = gen(deep,computerColor==4?5:4);
    for(int i = 0;i<points.count();i++)
    {
        chess[points[i].x()][points[i].y()] = computerColor==4?5:4;

             int v = max2(deep-1,alpha,best < beta ? best : beta,points[i]);
             if(v<best)
             {
                 best = v;
             }
         chess[points[i].x()][points[i].y()] = 0;
         if(v<alpha)
         {
            break;
         }
    }
    points.clear();
    return best;
}