前面讲到了算杀,其实在算杀之前应该讲一下迭代加深。因为这些文章是我边做边写的一些笔记,所以顺序上可能不是那么严谨。 按照前面的所有算法实现之后(当然不包括算杀),会发现一个比较严重的问题,就是电脑在自己已经胜券在握的情况下(有双三之类的棋可以走),竟然会走一些冲四之类的棋来调戏玩家。这种走法出现的本 ...
分类:
编程语言 时间:
2016-10-21 16:15:30
阅读次数:
383
关于剪枝问题 前面讲到的通过Alpha-Beta剪枝和启发式搜索可以将4层搜索的平均时间降低到1秒以下。只有这两个优化方式其实目前最多可以做到6层搜索,就是把AI和玩家各向后推算三步。 6层搜索的棋力其实相当弱,碰到经常玩五子棋的人基本都会输,更不要说对五子棋有研究的玩家。以目前的平均一个节点有50 ...
分类:
编程语言 时间:
2016-10-21 16:10:49
阅读次数:
403
为什么需要重构 之前的代码有很多松散的模块组合在一起。在把 Zobrist 集成进去时,会发现全部需要走棋的操作其实都需要进行一次 Zobrist 异或操作。另外在逻辑上,其实很多模块都是可以合并到同一个类的,所以这次把代码进行了一次大的重构。所以如果发现博客说的一些模块找不到了也是很正常的,因为大 ...
分类:
编程语言 时间:
2016-10-21 15:51:52
阅读次数:
186
这个博客不是把五子棋算法研究透彻之后再写的,而是一边研究算法一边写代码,同时一边写博客,所以有些博文的顺序不太对,比如 Zobrist 其实应该放在算杀之前就讲的。不过这并没有大的影响,总体上的顺序是OK的。 另外,这一系列博客讲的五子棋代码其实是一个开源的项目,源码地址:https://githu ...
分类:
编程语言 时间:
2016-10-21 15:46:15
阅读次数:
417
AI实现的基本思路-极大极小值搜索算法 五子棋看起来有各种各样的走法,而实际上把每一步的走法展开,就是一颗巨大的博弈树。在这个树中,从根节点为0开始,奇数层表示电脑可能的走法,偶数层表示玩家可能的走法。 假设电脑先手,那么第一层就是电脑的所有可能的走法,第二层就是玩家的所有可能走法,以此类推。 我们 ...
分类:
编程语言 时间:
2016-10-21 13:37:25
阅读次数:
548
剪枝是必须的 上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义。 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250000,在我的酷睿I7的电脑上一秒钟能计算的节点不超过 5W 个,那么 625W 个节点需要的时间在 ...
分类:
编程语言 时间:
2016-10-21 13:35:36
阅读次数:
691
#include <iostream> #include <conio.h> using namespace std; #define WIDE_AND_LONG 20 // 棋盘的长和宽 #define NAME_LEN 20 //输入姓名的长度 typedef class Gobang { pu ...
分类:
其他好文 时间:
2016-10-21 10:47:23
阅读次数:
222
重拾 C 语言之后发现,原来 C 语言是那么的简洁,对于写小项目来讲,C 语言是那么的合适,然后,博主自己写了一个五子棋游戏,同样是基于博主自己封装的 nkCEngine 代码库编写,其实整个游戏里面大部分代码都用在逻辑处理上了,图形处理以及窗口创建的部分,因为有高度封装的 nkCEngine,基本 ...
分类:
编程语言 时间:
2016-10-12 22:27:28
阅读次数:
217
技术路线 GUI的实现 棋盘的绘制 落子位置的判定 胜利条件判定算法 4条线分为8个方向,两两对称。因为情况很多,所以我构造了两个数组,dx和dy,如图: 将数组从[0,3][4,7]分为两部分,分别对应四条线每条线的两个方向。 如此只需循环遍历8个方向,每个方向出发的4个棋子子,统计这些棋子有多少 ...
分类:
其他好文 时间:
2016-10-08 19:52:43
阅读次数:
153
1 #include<iostream> 2 #include<iomanip> 3 using namespace std; 4 5 const int X = 21; //棋盘行数 6 const int Y = 21; //棋盘列数 7 char p[X][Y]; //定义棋盘 8 int m ...
分类:
编程语言 时间:
2016-10-05 10:47:48
阅读次数:
312