内容:走法产生

中国象棋基础搜索AI,

   极大值,极小值剪枝搜索,

   静态估值函数

理论基础:

   (一)人机博弈走法产生:

    先遍历某一方的所有棋子,再遍历整个棋盘,得到每个棋子的所有走棋情况(效率不高,可以改进)

 void SingleGame::getAllPossibleMove(QVector<Step *> &steps)
{
int min, max;
if(this->_bRedTurn)
{
min = , max = ;
}
else
{
min = , max = ;
} for(int i=min;i<max; i++)
{
if(this->_s[i]._dead) continue;
for(int row = ; row<=; ++row)
{
for(int col=; col<=; ++col)
{
int killid = this->getStoneId(row, col);
if(sameColor(i, killid)) continue; if(canMove(i, killid, row, col))
{
saveStep(i, killid, row, col, steps);
}
}
}
}
}

   (二)棋局博弈树理论:

    名词:对抗性搜索(Adversarial Search):敌对双方交替动作的搜索

    博弈树:树的根部是棋局的初始局面,根的若干子节点是有甲的每一种可能走法生成的局面,

        这些节点的子节点则是由乙的每一种可能走法生成的局面,如此交替直到棋局结束。

    

博弈树形象表示

    

   基于博弈树的游戏:

     计甲胜为WIN,乙胜为LOST,和局为DRAW;

     轮到甲走时,甲选择通向WIN或DRAW的节点;换言之,turn 甲,选择所有子节点中最好的(对甲);

     轮到乙走时,乙选择通向LOST或DRAW的节点;turn 乙,选择所有子节点中最差的(对甲);

  (三)极大极小值算法

    在上述博弈树基础上,令甲胜的局面值为1,乙胜的局面值为-1,和局的局面值为0;

    轮到甲走时,选择子节点值最大的走法,轮到乙走时,选择子节点值最小的走法;

    中间节点的值的确定:该局面轮到甲走,选择其子节点中的最大值,

              该局面轮到乙走,选择其子节点中的最小值。

    问题:实际的棋局不能简单的以1,-1,0三种状态表示,

       需要加入评估棋局局面分数的估值函数,配合博弈树的搜索来确定局面分数。

    实际解决方案:

       估值函数:暂时以静态估值的方式形成估值函数(评估较为粗糙),

            将棋局中的每个棋子按照重要程度赋一个值,

            估值函数通过计算一方现存棋子的总分数来确定局面优劣情况。

       代码示例:

 int SingleGame::score()
{
enum TYPE{CHE, MA, PAO, BING, JIANG, SHI, XIANG};
int s[] = {, , , , , , , , , , , , , , , };
//int s[] = {1000,450,501,200,15000,200,200};
/*当头卒比重大*/
int scoreBlack = ;
int scoreRed = ;
/*计算红方分数*/
for(int i=; i<; ++i)
{
if(_s[i]._dead) continue;
//scoreRed += s[_s[i]._type];
scoreRed += s[i];
}
/*计算黑方分数*/
for(int i=; i<; ++i)
{
if(_s[i]._dead) continue;
//scoreBlack += s[_s[i]._type];
scoreBlack += s[i-];
}
return scoreBlack - scoreRed;
}

      极大值极小值搜索方案:

       深度优先搜索,优点是不必在内存中生成整个博弈树,可以将搜索过的部分从内存中去除,

       采用递归形式,依次在min(int level,int curMin),max(int level,int curMax)之间递归调用,

       剪枝以去除不必要的步数,在求极大值时,若下一步的值小于当前极大值,直接删除这一步,不予考虑,

                   在求极小值时,若下一步的值大于当前极小值,直接删除这一步,不予考虑。

       在所有子节点中选出值最大的走法,就是电脑的最佳走法。

       代码示例:

 int SingleGame::getMinScore(int level, int curMin)
{
if(level == )
return score(); QVector<Step*> steps;
getAllPossibleMove(steps);
int minInAllMaxScore = ; while(steps.count())
{
Step* step = steps.last();
steps.removeLast(); fakeMove(step);
int maxScore = getMaxScore(level-, minInAllMaxScore);
unfakeMove(step);
delete step; if(maxScore <= curMin)
{
while(steps.count())
{
Step* step = steps.last();
steps.removeLast();
delete step;
}
return maxScore;
} if(maxScore < minInAllMaxScore)
{
minInAllMaxScore = maxScore;
}
}
return minInAllMaxScore;
}
int SingleGame::getMaxScore(int level, int curMax)
{
if(level == )
return score(); QVector<Step*> steps;
getAllPossibleMove(steps);
int maxInAllMinScore = -; while(steps.count())
{
Step* step = steps.last();
steps.removeLast(); fakeMove(step);
int minScore = getMinScore(level-, maxInAllMinScore);
unfakeMove(step);
delete step; if(minScore >= curMax)
{
while(steps.count())
{
Step* step = steps.last();
steps.removeLast();
delete step;
}
return minScore;
}
if(minScore > maxInAllMinScore)
{
maxInAllMinScore = minScore;
} }
return maxInAllMinScore;
}

            代码示例:

 Step* SingleGame::getBestMove()
{
Step* ret = NULL;
QVector<Step*> steps;
getAllPossibleMove(steps);
int maxInAllMinScore = -; while(steps.count())
{
Step* step = steps.last();
steps.removeLast(); fakeMove(step);
int minScore = getMinScore(this->_level-, maxInAllMinScore);
unfakeMove(step); if(minScore > maxInAllMinScore)
{
if(ret) delete ret; ret = step;
maxInAllMinScore = minScore;
}
else
{
delete step;
}
}
return ret;
}

    一个简单的象棋AI,还有诸多优化之处,目前搜索深度最大为4,与初级玩家对弈输多胜少。

Qt版本中国象棋开发(四)的更多相关文章

  1. Qt版本中国象棋开发(一)

    开发目的:实现象棋人机对战简单AI,网络对战,移植到android中. 开发平台:windows10 + Qt5.4 for android 开发语言:C++ 开发过程:1.棋盘绘制: 方法一:重写  ...

  2. Qt版本中国象棋开发(三)

    实现功能:棋子初始化及走棋规则 棋子类: #ifndef STONE_H #define STONE_H #include <QString> class Stone { public: ...

  3. Qt版本中国象棋开发(二)

    实现功能:棋盘绘制 核心函数: void paintEvent(QPaintEvent *); //QWidget自带的虚函数,重写后使用 QPainter 类来绘制图形 QPainter paint ...

  4. 基于QT的中国象棋

    基于QT的中国象棋,可实现人人对战,人机对战,联网对战,可显示棋谱,可悔棋. 还有一些小毛病,我之后会找空把这个DEMO重新修改一下上传 链接:https://pan.baidu.com/s/1-eM ...

  5. Cocos2d-X开发中国象棋《四》设计游戏场景

    设计完開始界面后就要设计游戏界面了 为了理清设计思路先看一张游戏界面效果图 游戏界面设计思路: 1.在窗体上放一张桌子 2.在桌子上放一个棋盘 3.在棋盘右边加入新局button,暂不实现详细的功能 ...

  6. Qt绘制中国象棋棋盘

    这里主要用的是#include <QPainter>里面的paintEvent void Board::paintEvent(QPaintEvent*) { QPainter painte ...

  7. Cocos2d-X开发中国象棋《二》project文件概述

    我在上一篇博客中介绍了象棋的功能.在接下来的博客中将向大家介绍使用Cocos2d-X怎样一步一步开发中国象棋 开发工具: Cocos2d-X2.2.3 VS2012 项目的文件夹: Classes:存 ...

  8. Python开发中国象棋实战(附源码)

        Pygame 做的中国象棋,一直以来喜欢下象棋,写了 python 就拿来做一个试试,水平有限,电脑走法水平低,需要在下次版本中更新电脑走法,希望源码能帮助大家更好的学习 python.总共分 ...

  9. cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面

    之前两个博客讲述了象棋的规格和工程文件之后,我们继续深入的从代码开始学习cocos2dx 首先从程序入口main函数开始 main函数 int APIENTRY _tWinMain(HINSTANCE ...

随机推荐

  1. Linked List-2

    三.编码技巧 1.遍历链表 先将head指针赋值给一个局部变量current: //return the number of nodes in a list (while-loop version) ...

  2. Blog Customization

    0 前言 从大二开始写博客,主要为了记录自己学习过程中的问题.尝试使用过CSDN.博客园等公共服务,也用Github pages搭建过自己的博客,但效果都不令人满意.CSDN广告太多,界面乌烟瘴气,而 ...

  3. 网速慢?NO可能是路由器的原因?

    先排除DNS的问题:看这个! 为什么我家300M的网,而且wifi信号满格,还是网速很慢? 这时候不排除是路由器的原因! 第一步首先我们要知道自己家的网关IP: 什么是网关? 网关(Gateway)又 ...

  4. Nacos作为配置中心时,多个服务共用一个dataId的配置

    写在前面 本文是对我之前一篇文章<Spring Cloud+nacos+Feign,实现注册中心及配置中心>的补充.此文章中简单写了如何将Nacos作为配置中心.在使用配置中心时,我们会遇 ...

  5. Android JetPack组件-CameraX初探

    CameraX 又是一个 Google 推出的 JetPack 组件 ,是一个新鲜玩意儿,故给大家分享下我在项目中的使用过程心得.. CameraX 是什么? Google 开发者文档 对 Camer ...

  6. P1714切蛋糕(不定区间最值)

    题面 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值. 小Z作为寿星,自然希望吃到的第一块蛋糕的幸运值总和最大,但小Z最多又 ...

  7. java线程池原理解析

    五一假期大雄看了一本<java并发编程艺术>,了解了线程池的基本工作流程,竟然发现线程池工作原理和互联网公司运作模式十分相似. 线程池处理流程 原理解析 互联网公司与线程池的关系 这里用一 ...

  8. 王颖奇 20171010129《面向对象程序设计(java)》第十五周学习总结

    实验十五  GUI编程练习与应用程序部署 实验时间 2018-12-6 学习总结: 理论部分: ◼ JAR文件◼ 应用程序首选项存储◼ Java Web Start JAR文件: 1.Java程序的打 ...

  9. 【HBase】HBase和Sqoop整合

    目录 需求一 步骤 一.修改sqoop配置文件 二.在mysql中创建数据库和数据表并插入数据 三.将mysql表中的数据导入到HBase表中 四.在HBase表中查看数据 需求二 步骤 一.创建hi ...

  10. 数据结构之栈(stack)的实现

    一.栈 1.定义 栈的英文为(stack),是一种数据结构 栈是一个先入后出(FILO-First In Last Out)的有序列表. 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同 ...