前言:上一期博客介绍了最为简单的人机博弈算法,包括获取所有合法路径、简单的估值以及电脑走棋。本期博客的进阶之处在于,所介绍的估值算法是建立在上一期博客的简单估值函数基础上的极大极小值算法(Minimax算法)。
关于极大极小值算法:
极大极小值算法是一种找出失败的最大可能性中的最小值的算法(即最小化对手的最大得益)。举个例子,电脑为A,人类为B,A在走棋之前需要思考,A走了某一步后,看看B有哪些走法,B又不傻,所以B肯定是要选择让A得分最少的走法走棋,而A就是在A的所有走法中选择B给出的让A得分最少的走法中得分最多的走法。听起来大概会比较抽象比较绕吧,试着多读几遍,多理解理解。
给电脑配置极大极小值算法让电脑选择走棋路径大概分3步走(还是电脑为A,人类为B):
1.在当前局面下获取A的所有走棋路径,并试着走一下。
2.在上一步(A已经试着走了一下)的基础上获取B的所有走棋路径,并以B的视角试着走一下,然后评估局面分(因为A是电脑,所以局面分是以A的角度计算的,即A的总分-B的总分),遍历完B的所有走棋路径后返回这些局面分中的最小值(对A最不利而对B最有利)。
3.在上一步返回的局面分的最小值中,找到最大值,并锁定与该最大值对应的走棋路径作为返回值返回。
因为现今既需要获取电脑的所有走棋路径又需要获取人类的所有走棋路径,所以对getAllPossibleMove函数稍微修改一下:
//获取所有走的通的走法存放在数组steps里
void SingleGame::getAllPossibleMove(QVector<Step *>& steps)
{
int min=16,max=32;
if(this->_bRedTurn)
{
min=0,max=16;
}
//遍历所有棋子
for(int i=min;i<max;i++)
{
//如果棋子已死则直接跳过
if(_s[i]._dead) continue;
//遍历所有行坐标