点击上方“程序人生”,选择“置顶公众号”
第一时间关注程序猿(媛)身边的故事
作者
De掉所有bug
来源
https://blog.csdn.net/weixin_41676881/article/details/83340873
如需转载,请联系我们。
人机对战类:- #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容器,其内部情况是这样的:
- #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函数源代码:- 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函数的源代码:
- void SingleGame::getAllPossibleMove(QVector& steps){ //遍历所有黑方棋子 for(int i=16;i_killid); moveStone(step->_moveid,step->_killid,step->_rowTo,step->_colTo);}
复制代码- 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 |
|