C++ QT中国象棋项目讲解(五) 人机对战两步搜索

根据博弈树的图,使用最小值最大值算法,当棋子fakemove一步之后,人必然会走局面分最小的一步,所以选择的走法就是最小值的最大值,修改几个关键的函数

Step* SingleGame::getBestMove()
{
    QVector<Step *> steps;
    //看看有哪些步骤可以走
    getAllPossibleMove(steps);
    int maxScore=-100000;
    Step* ret;
    for(QVector<Step*>::iterator it=steps.begin();it!=steps.end();++it)
    {
        Step* step=*it;
        //试着走一下
        fakeMove(step);
        //评估局面分
        int score=getMinScore();
        //再走回来
        unfakeMove(step);
        //取最高的分数
        if(score>maxScore)
        {
            maxScore=score;
            ret=step;
        }
    }
    return ret;
}

getMinScore由人的视角进行评估

int SingleGame::getMinScore()
{
    QVector<Step*> steps;
    //获取人类的所有走棋路径
    getAllPossibleMove(steps);
    int minScore=100000;
    for(QVector<Step*>::iterator it=steps.begin();it!=steps.end();++it)
    {
        Step* step=*it;
        //以人类的视角试着走一下
        fakeMove(step);
        //评估局面分
        int score=calcScore();
        //再走回来
        unfakeMove(step);
        //找到对电脑最不利的分数作为返回值返回
        if(score<minScore)
        {
            minScore=score;
        }
    }
    return minScore;
}

所以此时getAllPossbileMove不仅搜索红棋,还要搜索黑棋

//获取所有走的通的走法存放在数组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;
        //遍历所有行坐标
        for(int row=0;row<=9;row++)
        {
            //遍历所有列坐标
            for(int col=0;col<=8;col++)
            {
                //获取想要杀死的棋子的id
                int killid=this->getStoneId(row,col);
                //若想要杀死的棋子与行走的棋子颜色相同则跳过
                if(sameColor(killid,i)) continue;
                //判断某一棋子能不能行走
                if(canMove(i,killid,row,col))
                {
                    //将可以行走的“步”存放到steps中
                    saveStep(i,killid,row,col,steps);
                }
            }
        }
    }
}

这就构成了两部搜索的算法。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值