我们可以根据吃子棋的规则,创建走法生成器,主要的逻辑是,如果己方存在一气的棋串,则可以无需紧对方的气,也就是可以不用贴着对方的棋子落子。其他情况下,必须贴

着对方的棋子落子,考虑到某些特殊情况,当己方能提对方棋子时,己方就可以下到没有气的地方,并且一般的吃子棋,先提子者胜,无法形成劫争。所以走法生成器就相对非

常简单。

对于如何确定己方是不是存在一气的棋串,可以利用上一节介绍的算气算法。

  1 int CMoveGenerator::CreatePossibleMove(BYTE position[GRID_NUM][GRID_NUM], int nPly, int nSide)
  2 {
  3     m_nMoveCount = 0;
  4
  5     BYTE antiSide = (nSide + 1) % 2;
  6     cleanGlobal();
  7     setGo(position);
  8
  9
 10
 11     //检测己方是否有一气的棋窜,有则输出相应走法。
 12
 13     for (int i = 0; i < GRID_NUM; i++)
 14     for (int j = 0; j < GRID_NUM; j++){
 15
 16         if(go[i][j]==nSide&&g_gozi[i][j]==0){
 17            str_lib(i,j,go[i][j]);
 35
 36            if (goqi==1)
 37                 {
 38
 39                 for (int k = 0; k < GRID_NUM; k++)
 40                 for (int w = 0; w < GRID_NUM; w++){
 41
 42                 if (gokong[k][w] == 1){
 43                 AddMove(k, w, nPly);
 44
 45                 }
 46
 47
 48                 }
 49
 50
 51                 }
 52
 53         }
 54
 58     }
 59     64
 65     //正常情况下,寻找敌方棋子周边的空位,紧其气
 67
 68             for (int i = 0; i < GRID_NUM; i++)
 69             for (int j = 0; j < GRID_NUM; j++)
 70             {
 71
 72
 73             if (go[i][j] == antiSide)
 74             {
 75
 76                 if (i > 0 && go[i - 1][j] == NOSTONE){
 77
 79                     AddMove(i - 1, j, nPly);
 80
 81
 82                 }
 83
 84                 if (i < GRID_NUM - 1 && go[i + 1][j] == NOSTONE){
 85
 87                     AddMove(i + 1, j, nPly);
 88
 89                 }
 90
 91                 if (j>0 && go[i][j - 1] == NOSTONE){
 92
 94                     AddMove(i, j - 1, nPly);
 95
 96
 97                 }
 98
 99                 if (j < GRID_NUM - 1 && go[i][j + 1] == NOSTONE){
100
102                     AddMove(i, j + 1, nPly);
103
104                 }
105
106
107             }
108
109
110
111         }
112
113
114
115     return m_nMoveCount;
116 }

可以优化此算法,以后方便后续的搜索引擎进行剪枝。给走法设定一个分数,能够提子则此步设为30+提子数。能够打吃则为20+打吃棋子数(打吃未必是好棋,不这么做了)。能够长气,则为10+长气的棋子数。其他暂时设计为0。可以用一个额定长度的优先队列,保留几个分数最佳的走法。或是必要时进行排序。

搜索时优先优先搜索得分较高的走法,这样大幅度提高搜索算法剪枝的效率。

这段是走法启发的代码

伪码如下:

 1 for(int i=0;i<Grid_Num;i++)
 2 for(int j=0;j<Grid_Num;j++)
 3 {
 4     cleanupGlobal();
 5     if(go[i][j]==NOSTONE)
 6     {
 7     bool isVilid=false;
 8     if(i>0&&go[i-1][j]==antiSide)
 9     {
10
11        go[i][j]=nSide;
12
13        if(g_gozi[i-1][j]==0)
14        {
15           isVilid=true;
16           str_lib(i-1,j,antiSide);
17           if(goqi==0){....}
18
19        }
20
21     }
22      if(i<Grid_Num-1&&go[i+1][j]==antiSide)
23      {
24
25
26        go[i][j]=nSide;
27
28
29        if(g_gozi[i-1][j]==0)
30        {
31           isValid=true;
32           str_lib(i-1,j,antiSide);
33           if(goqi==0){....}
34        }
35
36
37     }...
38          if(isValid)
39          {
40           sumScore(i,j,nSide);
41           addMove(i,j,nSide);
42           }
43 44
45
46
47     }
48 }
49 std::sort();   random_shuffle(begin+offset,end);

这个算法是走法启发,学名为静态启发,而不是历史启发,历史启发并不需要棋类的知识属于动态启发,而走法启发则与棋类知识相关联。

现在的思路是,长气和提子的走法绝对的好走法,而把对方打成1气的走法未必是好的走法,要考虑到自身有没有受到攻击,以及我方有人没有薄弱的地方,以及能否征吃。所以我们只需要将吃子的下法,按吃子多少排序即可。这样也可以提高剪枝效率,并且不至于把坏的走法提高的前面。

最近,无意中写出了一个新的功能,由于棋盘的对称性或非对称估值核心返回值碰巧相同,会导致一些走法的分数是相同的,我们的搜索算法会认为分数一样,优先选择排在前面的走法。其实我们应该对分数一直的走法随机的进行选择,这样我们的程序就不会变得死板。那么如何实现呢?我们在生成走法时,将绝对好的走法排在最前面,将看起来差不多的走法乱序一下,这样当返回时,分数一样的走法的排序也是乱序的,由于我们的搜索算法总是选择已经乱序过后的第一个,那么走法也是随机的。

转载于:https://www.cnblogs.com/tangzhenqiang/p/4020739.html

人机博弈-吃子棋游戏(三)走法生成相关推荐

  1. 人机博弈-吃跳棋游戏(三)代移动

    我们能够根据国际象棋的规则吃,创建移动生成器.基本逻辑是,假定一个拉伸己方蠕虫的存在,这是可能没有其他的致密气.这是不是对其他部分可以落子.在其他情况下.必须坚持 另一片落子,考虑到特殊情况,当自己可 ...

  2. 基于C#实现的支持AI人机博弈的国际象棋游戏程序

    1 背景和意义 1.1 项目意义 该项目的成功推进和完成将达到 AI 比赛过程自动化的目的,有助于比赛的顺畅.成功开展以及比赛时间的有效节约 该项目的成果将有助于<人工智能原理>课程的学生 ...

  3. [源码和文档分享]基于C#实现的支持AI人机博弈的国际象棋游戏程序

    1 背景和意义 1.1 项目意义 该项目的成功推进和完成将达到 AI 比赛过程自动化的目的,有助于比赛的顺畅.成功开展以及比赛时间的有效节约 该项目的成果将有助于<人工智能原理>课程的学生 ...

  4. c# sigmoid_[源码和文档分享]基于C#实现的支持AI人机博弈的国际象棋游戏程序

    1 背景和意义 1.1 项目意义 该项目的成功推进和完成将达到 AI 比赛过程自动化的目的,有助于比赛的顺畅.成功开展以及比赛时间的有效节约 该项目的成果将有助于<人工智能原理>课程的学生 ...

  5. C语言实现人机模式三子棋游戏

    三子棋规则:在九宫格棋盘上,只要将自己的三个棋子走成一条线(横排.竖排.对角线),就算对方输了. 接下来,我们就开始用C语言实现这款操作简单容易上手的小游戏.我们采用多文件方式实现: game.h// ...

  6. 基于Alpha-Beta剪枝树的井字棋人机博弈实现

    1 Alpha-Beta剪枝树的简单介绍 Alpha-Beta剪枝的本质就是基于极小化极大算法的一种改进算法.因此先简单地介绍下极小化极大算法,这样有利于我们更好的理解Alpha-Beta剪枝算法. ...

  7. 【Qt象棋游戏】08_人机博弈高阶算法

    文章目录 01 - 极大极小值算法 02 - 电脑和人类所有走棋路径 03 - 走一步看两步 04 - 走一步看多步 04 - 总结 01 - 极大极小值算法   上一期博客介绍了最为简单的人机博弈算 ...

  8. 基于QT实现的alpha-beta剪枝算法搜索的象棋人机博弈游戏

    中国象棋是一个古老的而富有智慧的游戏,而中国象棋博弈程序是将计算机知识和中国象棋知识结合起来的一种新型的游戏方式.它以一种全新的人机博弈方式突破了以往传统象棋游戏只能人与人对战的限制,使得这个古老的游 ...

  9. 【Qt象棋游戏】07_人机博弈算法开端

    文章目录 01 - 人机博弈算法简述 02 - 相关成员与方法 03 - 获取电脑棋子能走路径 04 - 电脑走棋 05 - 总结 01 - 人机博弈算法简述   前面详细介绍了棋盘类的封装.棋子类的 ...

最新文章

  1. Xcode 调试的正确打开方式——Debugging
  2. 德鲁克的17条思想精髓,读懂管理的本质
  3. 为什么函数式编程很重要:不一样的白板图
  4. Matplotlib学习---用matplotlib画误差线(errorbar)
  5. SQL SERVER 参考:游标(Cursor)的讲解与实例
  6. 接口批量同步数据_千手接口平台+电商ERP,助德嵘大药房征战拼多多
  7. MySQL_多表链接查询
  8. Spring整合RabbitMQ
  9. datareader对象转化为int_【Angew. Chem. Int. Ed.】光催化丙二烯的去消旋反应
  10. 无人驾驶(再谈基于camera的高精度地图)
  11. (转)OAuth 2.0的设计思路
  12. 安装Visio 2016与原本的office冲突的最终解决方案
  13. 利用Docker学习Redis笔记(一)
  14. XenApp/XenDesktop 7.12新功能LHC解读
  15. 附全文 |《数字中国指数报告2019》重磅发布,下一个数字经济增长点将由产业驱动...
  16. intel h61 linux驱动下载,intel h61主板驱动
  17. 计算机网络的常用命令汇总
  18. OKR | 我们的目标是称霸全国!
  19. onfocus获取焦点事件与onblur失去焦点事件
  20. iPhone 15 高端版本万元起步;华为授权 OPPO 使用其 5G 技术;DeepMind 推出 AI 编剧|极客头条...

热门文章

  1. 企业信用等级评价流程
  2. python代码写开心消消乐
  3. softmax回归梯度公式推导及实现
  4. C++Vector定义二维数组
  5. 浅析部署微软 AD 的 4 个隐性成本
  6. Java 进阶——多线程优化之线程池 ThreadPoolExecutor的使用(三)
  7. ArcGIS 城市生活区用地适宜性评价(四)
  8. jq修改input、textarea只读,不可修改
  9. 在线支付系列【7】微信支付接入指引
  10. CMMI认识和访谈的一些问题