OPE电竞_ope电竞app_ope电竞app官网
OPE电竞

伊一,象棋人工智能算法的C++完成(四)——人工智能的初步,惊悚乐园

admin admin ⋅ 2019-04-11 09:00:55

点击上方“程序人生”,挑选“置顶大众号”

第一时间重视程序猿(媛)身边的故事


作者

De掉一切bug 

来历

https://blog.csdn.net/weixin_41676881/article/details/83340873 

如需转载,请联络咱们。


前面几篇文章具体介绍了棋盘类的封装、棋子类的封装以及各种类型的棋子的走棋算法的完结。有了前面的衬托,就能迈出人工智能的第一步了。本系列博客仍是要点介绍完结办法,许多的代码都不再过多解说了。


象棋人工智能算法的C++完结(三)——重视功用分区!!!

象棋人工智能算法的C++完结(二)

象棋人工智能算法的C++实姑侄通奸现(一)


人机对战类:

#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 getAllPo香痰盂ssibleMove(QVector& steps);
   //评价局势分
   int calcScore();
&香港三nbsp;  //伪装走一步
   void fakeMove(Step* step);
   //将伪装走的那一步挪回来
   void unfakeMove(Step* step);
   //获取最佳走棋途径
   Step* getBestMove();
   //电脑走棋
   void computerMo宋东发ve();
};

#endif // SINGLEGAME_H


由以上代码能够看出,人机对战类承继自棋盘类,重载了棋盘类中的click函数。其间,Step是一个QVector容器,其内部状况是这样的:


#ifndef STEP_H
#define STEP_H

#include

class Step : public QObject
{
   Q_OBJECT
public:
   explicit Step(QObject *parent = 0伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土);
   ~Step();

   //行走棋子的id
   int _moveid;
   //杀掉棋子的id
   int _killid;
   //开始行坐标
   int _rowFrom;
   //开始列坐伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土标
   int _colFrom;
   //方针方位行坐标
   int _rowTo;
  &n俏厨娘不嫁闷将军bsp;//方针方位列坐标
   int _colTo;

signals:

public slots:
};

#endif //伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土 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& st伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土eps)
{
   //遍历一切黑方棋子
   for(int i=16;i<32;i++)
   {
       //假如棋子已死则直接越过
       if(_s[i]._dead) continue;
       //遍历一切行坐标
       for(int row=0;row<=9;row++)
&软心装置器nbsp;      {
           //遍历一切列坐标
          梁继志 for(int col=0;col<=8;col++)
           {
               //获取想要杀死的伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土棋子的id
               int killid=this->getStoneId(row,col);
               //若想要杀死的棋子与行走的棋子色彩相同则越过
               if(sameColor(killid,i)) continue;
      uie耍大牌损伤光洙         //判别某一棋子能不能行走
&nbs死者刘海龙p;              if(canMove(i,killid,row,col))
               {
                   //将能够行走的“步”寄存到steps中
                   saveStep(i,killid,row,col,steps);
               }
         重生之黄埔军魂;  }
       }
   }
}


算法解析:遍历一切黑方的棋子,遍redhead历到某一棋子时全方位无死角地遍历棋盘上的一切方位,把每个方位的信息都输入canMove函数,将canMove函数回来true的“步”寄存到容器steps中。

2.从一切能走的途径中找到对电脑最有利的途径

上getBestMove函数的源代码:

Step* SingleGame::getBestMove()
{
  &张秋芳和新老公相片nbsp;QVector steps;
   //看看有哪些进程能够走
   getAllPossibleMove(steps);
  胡凯钰 int maxScore=-100000;
   Step* ret;
   for(QVector::iterator it=steps.begin();it!=steps.end();++it)
   {
       Step* step=*it;
       //试着走一下
       fakeMove(step);
       //评价局势分
      &nb伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土sp;int s芳芯core=calcScore();
       //再走回来
      &nbmc鬼鬼于航sp;unfakeMove(step);
       //取最高的分数
       if(score>maxScore)
       {
           maxScore=score;
           ret=step;
       }
   }
   return ret;
}


算法解析:这便是模拟人的思想的进程,从小跟爷爷下棋的时分爷爷就对我说,要走一步看三步,但是这儿先完结走一步看一步。路旁边两个老爷爷在下棋,老爷爷尽管不会耍弄棋盘上的棋子,但是他的脑子里是在推演的,他也会权衡一下挑选对自己最有利的途径走棋。fakeMove和unfakeMove便是推演的进程,设想自己走一步,评价完局势分再走回来。找到走完后局势分最高的途径作为回来值回来。


关于fakeMove函数和unfakeMove函数:


void SingleGame::fakeMove(Step* step)
{
   伊一,象棋人工智能算法的C++完结(四)——人工智能的开始,惊悚乐土killStone(step->_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函数的源代码:

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<16;i++)
   {
       //假如棋子已死则越过累加
       if(_s[i]._dead)
           continue;
       redTotalScore+=chessScore[_s[i]._type];
   }
   //核算黑棋总分
   for(int i=16;i<32;i++)
   {
       //假如棋子已死则越过累加
       if(_s[i]._dead)
           continue;
       blackTotalScore+=chessScore[_s[i]._type];
   }
   //回来黑棋总分-红棋总分
   return blackTotalScore-redTotalScore;
}

算法剖析:先给一切棋子分配权重,依据棋子的重要程度来分配。将是最重要的棋子,因而将的权重最高,置为1500;车其次,置为100,马和炮再其次,置为50;兵再再其次,置为20;士和相最不重要,置为10。遍历红方一切的棋子,将红方活着的棋子的权重累加出一个总分;遍历黑方一切的棋子,将黑方活着的棋子的权重累加出一个总分。由于黑方是电脑,所以回来的局势分应该以黑方的视点核算,回来黑棋总分-红棋总分。


3.电脑走棋


这一部分在上面的click函数中有表现,请自行往上翻。


(完)

「若你有原创文章想与咱们共享,欢迎投稿。」

加修改微信ID,补白#投稿#:

程序 丨 druidlost  

小七 丨 duoshangshuang


引荐阅览:

  • 卖烤红薯也要懂OAuth2.0

  • 纵观 30 年 5000 多部国产电视剧,豆瓣评分最低的艺人原来是……

  • 全面整理百度国际大会,李彦宏又新吹了几个牛!

  • 她说:真的,没事别嫁程序员

  • 学习这么多算法到底在解徐允厚决哪些问题?深度学习之外,咱们要挑选谁?

  • 如何用编程 get 百万年终奖?


print_r('点个赞吧');
var_dump('点个赞吧');
NSLog(@"点个赞吧!")
System.out.println("点个赞吧!");
console.log("点个赞吧!");
print("点个赞吧!");
printf("点个赞吧!\n");
cout << "点个赞吧!" << endl;
Console.WriteLine("点个赞吧!");
fmt.Println("点个赞吧!")
Response.Write("点个赞吧");
alert(’点个赞吧’)

相关新闻

admin

admin

TA太懒了...暂时没有任何简介

精彩新闻