象棋人工智能算法的C++实现(四)——人工智能的开端

论坛 期权论坛 期权     
程序人生   2019-6-9 21:25   2364   0
点击上方“程序人生”,选择“置顶公众号”
第一时间关注程序猿(媛)身边的故事



作者
De掉所有bug
来源
https://blog.csdn.net/weixin_41676881/article/details/83340873
如需转载,请联系我们。
前面几篇文章详细介绍了棋盘类的封装、棋子类的封装以及各种类型的棋子的走棋算法的实现。有了前面的铺垫,就能迈出人工智能的第一步了。本系列博客还是重点介绍实现方法,很多的代码都不再过多解释了。

象棋人工智能算法的C++实现(三)——注重功能分区!!!
象棋人工智能算法的C++实现(二)
象棋人工智能算法的C++实现(一)
人机对战类:
  1. #ifndef SINGLEGAME_H#define SINGLEGAME_H #include "Board.h" class SingleGame : public Board{public:    virtual void click(int id,int row,int col);     //获取所有走棋路径存放到steps中    void getAllPossibleMove(QVector& steps);    //评估局面分    int calcScore();    //假装走一步    void fakeMove(Step* step);    //将假装走的那一步挪回来    void unfakeMove(Step* step);    //获取最佳走棋路径    Step* getBestMove();    //电脑走棋    void computerMove();}; #endif // SINGLEGAME_H
复制代码
由以上代码可以看出,人机对战类继承自棋盘类,重载了棋盘类中的click函数。其中,Step是一个QVector容器,其内部情况是这样的:
  1. #ifndef STEP_H#define STEP_H #include  class Step : public QObject{    Q_OBJECTpublic:    explicit Step(QObject *parent = 0);    ~Step();     //行走棋子的id    int _moveid;    //杀掉棋子的id    int _killid;    //起始行坐标    int _rowFrom;    //起始列坐标    int _colFrom;    //目标位置行坐标    int _rowTo;    //目标位置列坐标    int _colTo; signals: public slots:}; #endif // STEP_H
复制代码
由以上代码可以看出Step类是用来存放走棋信息的。
人机对战类中重载的click函数源代码:
  1. void SingleGame::click(int id,int row,int col){    if(!this->_bRedTurn)        return;     Board::click(id,row,col);     if(!this->_bRedTurn)    {        Step* step=getBestMove();        moveStone(step->_moveid,step->_killid,step->_rowTo,step->_colTo);    }}
复制代码
由以上代码可以看出,人类方走红棋,电脑方走黑棋。当轮到红方走棋的时候,与人人对战的时候没有区别,于是调用父类中的click函数;当轮到黑方走棋的时候,就获取对电脑最有利的走棋路径,让电脑走棋。

----这里是华丽的分割线----

人工智能的实现分3步走

1.获取所有走得通的路径

上getAllPossibleMove函数的源代码:
  1. void SingleGame::getAllPossibleMove(QVector& steps){    //遍历所有黑方棋子    for(int i=16;i_killid);    moveStone(step->_moveid,step->_killid,step->_rowTo,step->_colTo);}
复制代码
  1. void SingleGame::unfakeMove(Step* step){    reliveStone(step->_killid);    moveStone(step->_moveid,step->_rowFrom,step->_colFrom);}
复制代码
其中killStone函数是用来杀死棋子的,relieveStone函数是用来复活棋子的。
获取最优走棋路径这一步中有个很重要的步骤就是评估局面分,上calcScore函数的源代码:
[code]int SingleGame::calcScore(){    //枚举的 车=0 马=1 炮=2 兵=3 将=4 士=5 相=6    static int chessScore[]={100,50,50,20,1500,10,10};    int redTotalScore=0;    int blackTotalScore=0;    //计算红棋总分    for(int i=0;i
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:240
帖子:48
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP