四子棋对抗作业实验报告

参考了此篇博客:
UCT(信心上限树算法)解四子棋问题——蒙特卡罗法模拟人机博弈

实验思路

1、使用极大极小搜索树并配合 $ \alpha - \beta $ 剪枝。

2、使用蒙特卡洛搜索树结合UCB信心上限算法。

实验过程

由于不太清楚如何选择估值函数以及一些先验知识,最终选择UCT算法,即在蒙特卡洛树中运用UCB算法。

UCT算法原理

​ 上图是UCT算法的伪代码,当某个节点存在尚未扩展的子节点时,创建未扩展的节点;当某个节点所有子节点都已扩展,则按照UCB的策略进行选择最优的子节点。通过TreePolicy选出目前整棵树中当前的叶子节点,并在该节点进行模拟游戏直到终局分出胜负,然后将此次游戏结果向上传播给父节点以及祖先节点。这就算完成一次搜索,在设定的时间限制内重复该搜索,最后返回不考虑探索次数情况下(即UCB算法中的C值取0)根节点的最优子节点。

算法实现

​ 通过伪代码,可以抽象出状态节点的类,而UCT算法也可以封装成一个类。C值选取的是0.8,时间设置为2300ms。

优化

​ 1、初始版本由于每一次调用UCT算法进行搜索都要重新创建一个根节点并进行搜索。后来觉得上一次决策时的模拟结果就全都浪费掉了,应该可以保留对手所下位置的对应的那个分支,因此就把UCT算法改成了一个单例模式,在整个对弈过程中只有一个实例,只有一颗搜索树。每次轮到我方落子时,删除无用的子节点,然后移动根节点到对应的子节点。在我方选好落子的时候,同样要删除无用子节点,移动根节点。

实现如下:

//删去子节点落子为(x,y)以外的节点,并移动根节点
void UCT::chopBranches(int x, int y){StateNode* nextroot = this->root->deleteOtherBranches(x, y);if(nextroot != root){delete root;}nextroot->parent = nullptr;root = nextroot;
}
StateNode* StateNode::deleteOtherBranches(int x, int y){StateNode* retNode = this->child[y];for (int i = 0; i < this->N; i ++){if (this->child[i]) {if( y != i){this->child[i] -> clear();delete this->child[i];}}}//如果x,y对应的节点为空指针,说明该分支未被模拟过,则重新初始化根节点,并返回此节点if(retNode == nullptr){............}else{............}return retNode;
}

遇到的问题

1、考虑到在比较深的节点模拟成功,意味着步数太多,就容易给对手机会,因此觉得应该浅层时的胜利的收益更大。于是尝试在向上传播的函数中,修改为随着层数的增加,对上层的收益减小。但似乎起反作用。还有待研究。

2、发现存在这样的情况,在最终返回best节点时,根节点的某个子节点被探索太少次而未被选中,导致输了比赛。

3、使用测试文件夹中的compile.bat,编译时出现如下错误,vs2012版本从校园网软件中下载,但这个错误不影响生成dll文件。于是还是强行用该dll进行了测试。

4、使用compete.bat进行测试时,出现illegal step情况,经多次调试,以及检验逻辑后,并未找到错误,最后发现compete.bat调用compete.exe运行对抗,在对抗新一局时不会重启exe程序,而我的代码中UCT是一个单例,搜索树在新一局开始时不会更新,于是导致问题。因此做了修改,当判断到是新的一局游戏时,delete原root节点,新建root节点。在strategy.cpp中加入以下代码,判断是否是新一局游戏:

 //判断是否是新一局游戏int steps = 0;int newgameflag = 0;for(int i = 0; i < N; i++){steps += (M - top[i]);}if( noX == (M-1)){steps -= 1;}if(steps == 0 || steps == 1){newgameflag = 1;}

最终对阵结果:

最终手动开UI运行100次对抗的结果为 75胜25负,其中先手输给了40、66、74、78、82、84、86、88、92、98、100,后手输给了22、24、30、40、54、62、74、84、86、90、92、94、98、100。

错过ddl,决定优化一下

1、在观察AI对抗的时候发现,自己的ai经常不去防守对方必胜的落子点,而且考虑到对于已决出胜负的终节点,棋权为AI且AI存在必胜落子点,那就把这一落子点对应的节点的收益设置为最大,同时把该节点的父节点的收益设置为最小,意味着父节点的落子是必败的落子点。若某一方落子后,另一方的任何落子位置都必败,那个这个落子是必胜节点也可设置为收益最大。因此在defaultPolicy函数中加入以下代码:

     if(node->whoseNode == COMPUTER_NODE){if(node->nodestate == COMPUTER_WIN){node->profit = 1e14;node->parent->nodestate = COMPUTER_WIN;node->parent->profit = 1e14;}else if(node->nodestate == HUMAN_WIN){StateNode* parent = node->parent;int flag = 1;if(parent->canExpandNUms == 0){for( int i = 0; i < this->N; i++){if((parent->child[i]!=0)&&(parent->child[i]->nodestate != HUMAN_WIN)){flag = 0;break;}}}else{flag = 0;}if(flag == 1){node->parent->nodestate = HUMAN_WIN;node->parent->profit = -1e14;}}}

在加入以上策略后,对阵100的胜率有所上升。

2、关于C值的思考,进行微调发现设置为0.9时竟然对阵100的胜率上升了。而C值代表着倾向于探索访问过少的节点还是倾向于选择利用,因此产生了动态调整C值的想法。在游戏初期应更偏向于探索,终局以及后期偏向于利用,于是将C值乘以一个衰减系数,随回合数增加而减小,同时也设定了一个下限,不能过低。这似乎是个玄学调参的过程,对战所有文件的统计结果并不佳。

3、进行了代码发现在每一个rand()函数前都调用了srand(int(time(nullptr))),意味着一秒内的每一次rand()都是返回同样的值,这导致算法根本不随机,一秒内重复探索同一个位置。导致了之前胜率不高的问题。

最终提交结果:

在修复了bug后达到了如下成绩:

在查看每个compete_result文件后,认为前五项分别是学号、先手胜、后手胜、先手输、后手输。

也就是这一次结果为:先手胜50 后手胜48 后手输2,即 胜98, 平0,输2

总结:

两大改进对胜率有不错的提高:

1、每次轮到我方落子不是新建树,而是沿着树走到对应的节点,可以不丢失之前的模拟探索数据。

2、对于必胜节点的收益,引导ai往必胜节点走。分别有两种情况:

​ (1)、若某一个落子是必胜(必败)节点,则父节点状态改为必败(必胜),同时节点收益设为非常高(非常低),父节点收益设置为非常低(非常高)。

​ (2)、若某一个节点的所有子节点都是必胜(必败),则该节点设置为必败(必胜),节点收益设置为非常高(非常低)。

​ 在这两点改进后,可以减少在必败节点的搜索,提前判断出一些必胜分支。

进一步探索方向:

1、还是没太搞懂C值选取什么值最好。

2、极大极小α−β\alpha -\betaα−β剪枝,考虑尝试一下。在观察ai自动下棋时看出了一些规律。

3、了解一下alphaGo中蒙特卡洛的策略。

附在最后:

在提交了作业之后的这几天,又对代码进行了调试,发现由于一个小bug,第二点优化并没有起作用,又瞎折腾了几天,解决一些新bug,想尝试达到对阵100可以百分百胜率,最后出现了各种情况。最后心态暴毙,就此暂停,准备期末考试要紧。

UCT树用于四子棋对抗实验相关推荐

  1. 深圳大学计系汇编语言实验--四子棋游戏

    题面 四子棋是个双人游戏,两人轮流下棋,棋盘由行和列组成的网格,每个选手每次下一个子直到两人中有一人的棋子连成一条水平线.垂直线或者是对角线. 本实验需要在LC-3中实现简易版四子棋的游戏,两位选手通 ...

  2. 深圳大学 计系1实验四—四子棋实验

    实验要求 本实验需要在LC-3中实现简易版四子棋的游戏,两位选手通过键盘和输出窗口轮流交互操作,棋盘由6 X 6的网格组成. 游戏规则如下: 两位选手依次轮流落子: 选手不能悔棋: 有子的地方不能继续 ...

  3. java四子棋实验报告_Python 实现劳拉游戏的实例代码(四连环、重力四子棋)

    游戏规则:双方轮流选择棋盘的列号放进自己的棋子, 若棋盘上有四颗相同型号的棋子在一行.一列或一条斜线上连接起来, 则使用该型号棋子的玩家就赢了! 程序实现游戏,并将每局的数据保存到本地的文件中 首先我 ...

  4. python人机对战的实验步骤_人机对战初体验:Python实现四子棋游戏

    继去年3月人机大战引发全球瞩目以来,围棋AI(人工智能)再度引发跨领域的关注:一个叫Master的围棋AI,几天时间,面对中日韩顶尖职业围棋选手,已取得60胜0败的恐怖战绩,展现出的围棋技艺已经到了人 ...

  5. 基于LC3模拟器的简单游戏设计:简易四子棋

    一.实验目的 分析和理解指定的需解决问题. 利用LC-3的汇编代码设计实现相关程序. 通过LC-3仿真器调试和运行相关程序并得到正确的结果. 二.实验内容 四子棋是一款普遍流行的简易型桌面游戏,据说, ...

  6. 人机对战初体验:Python基于Pygame实现四子棋游戏

    人机对战初体验-四子棋游戏 继去年3月人机大战引发全球瞩目以来,围棋AI(人工智能)再度引发跨领域的关注:一个叫Master的围棋AI,几天时间,面对中日韩顶尖职业围棋选手,已取得60胜0败的恐怖战绩 ...

  7. 四子棋 freepython

    四子棋,是黑白棋的一种.是一种益智的棋类游戏.黑白两方(也有其它颜色的棋子)在8*8的格子内依次落子.黑方为先手,白方为后手.落子规则为,每一列必须从最底下的一格开始.依此可向上一格落子.一方落子后另 ...

  8. 四子棋游戏--bingo game

    最近自己编了一个四子棋的游戏.说明如下: 游戏简介: 一种常见的四子棋游戏,可以是人机对战,两人对战,或者网上对战. 游戏的双方轮流落子,每人持有21颗子.棋子共有6*7个位置,玩家的棋子总是落到 当 ...

  9. vb四环棋的实现,平面四子棋,四连环游戏

    vb四环棋的实现,平面四子棋 首先我们百度一下,什么是平面四子棋 相信很多小伙伴见到这幅图片都不陌生. 那么在代码中怎么实现呢?我们用vb代码为例子. 先看效果图 我们设计o和x是需要下的棋子,如果没 ...

  10. 全国大学生软件创新大赛一等奖作品 —— HyllCube 三维四子棋

    2011 年 9 月,那时刚升大三.和另外三位童鞋组队参加了第四届英特尔杯全国大学生软件创新大赛.最终,在北京的总决赛中,成功获得一等奖~ 时间过得真快,没想到,到现在已经有 8 年了~ 整个比赛过程 ...

最新文章

  1. running build_ext building ‘gensim.models.word2vec_inner‘ extension error: Microsoft Visua
  2. Ubuntu 16.04 LTS下编译GPU版tensorflow
  3. DataTables中设置checkbox回显选中
  4. 怎么利用ffmpeg和AviSynth给在windows下面为flv文件加水印
  5. Mysql8报You need either to explicitly disable SSL by setting useSSL=false
  6. 稳站大屏 AIoT 时代之巅,创维 Swaiot 生态品牌实现全面布局!
  7. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_5_同步技术的原理...
  8. linux编写python脚本_在ubuntu linux 中编写一个自己的python脚本
  9. linux web接口返回乱码,【bug】测试环境的API接口,返回内容为乱码
  10. skynet:cluster
  11. 互联网创业者必备的十种思维
  12. 计算机网络(3)--应用层协议--HTTP与HTTPS
  13. 202020 公文系统安装技巧
  14. Augustus指南(Trainning部分)
  15. Deep Photo的TensorFlow版本
  16. EndNote插入文献闪退
  17. oracle12.2+asm进程,Oracle12,1,2,0版本中遇到bug25211209
  18. 升级IDEA时出现Some conflicts were found in the installation area
  19. Hbase统计表的行数的3种方法
  20. 【论文阅读】Lie-Algebraic Averaging For Globally Consistent Motion Estimation

热门文章

  1. 周日报名截止,翼支付杯大数据建模大赛16万大奖邀你来!!
  2. ubuntu不支持安装搜狗_Ubuntu下安装搜狗输入法已经fcitx升级后搜狗输入法不能使用的解决办法...
  3. LIBSAS/SAS驱动代码分析(1)之概述
  4. 一个像素的旅行,卷积网络可视化项目火了:点点鼠标就能看懂的扫盲神器
  5. 【其它】怎样开启Win7快速启动栏
  6. 为什么手机里的小爱音响app里搜不到家里的小爱音箱_水哥岁末诚意奉献:基于米家App的家庭智能安全方案详解...
  7. impress.js css模板,使用impress.js制作幻灯片
  8. 360系统急救箱用在服务器上,360系统急救箱打开失败的处理操作
  9. 三苯基膦(TPP)负载碘化BODIPY光敏剂(BDPI)纳米颗粒(PBDPI-TPP)介绍
  10. wordpress mysql缓存_WordPress 如何启用 Memcached 内存缓存来提高网站速度