五子棋禁手判定算法

原创 2006年06月22日 21:57:00
         禁手的判定较为复杂,设计一个判断禁手的算法既要分析构成它的棋型又要找到合适的搜索方法。
         首先分析棋型。
先考虑构成长连禁手的棋型,构成长连的棋型较简单,可归纳为一种,即相连后形成六子或更多相连。一旦发现产生此棋型,即判为长连禁手。
再考虑构成四四禁手、三三禁手的棋型。要判断下某一子是否构成四四禁手(或三三禁手),只需判断下这一子后是否产生两个或两个以上的冲四或活四(或活三)即可。所以归结起来,要正确判断四四禁手、三三禁手就是要正确判断冲四、活四和活三。
考虑冲四、活四和活三的定义。冲四是只有一个点可以成五的四,这里我们将那个点称为关键点。同样,构成活四的有两个关键点,构成活三的有一个关键点。如图11a,b两点是其构成活四的关键点,又如图12a点是其构成活三的关键点。
 
 图1111
12
 
以下是对各棋型和关键点的分析。
1、活四:
归结起来构成活四的只有一种棋型,如图13
13
这种棋型真正构成活四的条件是左右两空位(即a,b点)必须是黑棋可下的点,也就是在a,b点下黑子后都不会构成禁手。
2、冲四:
形成冲四有两种棋型,如图14和图15
14
15
 
这两种棋型真正构成冲四的条件是中间的空位(即a点)必须是黑棋可下的点,也就是在a点下子后不会构成禁手。
3、活三:
形成活三有两种棋型,如图16和图17
16
17
其中,a点是关键点,b,c点可以是边界、无子或白色棋子,但不能是黑色棋子。
这两种棋型真正构成活三的条件是a点必须是黑棋可下的点,也就是在a点下子后不会构成禁手,m,n两点不用管是否构成禁手,因为当a点放入黑子后,不管在m点还是n点放黑子,就会形成五连,即获胜,不构成禁手。
所以我们要判断一种棋型是否构成冲四、活四或活三,需要在已判断它是可能的冲四、活四或活三的棋型的基础上判断它的关键点是否可落黑色棋子,也就是判断关键点是否不会构成新的禁手点,这一步在程序中可以用递归实现。
 
棋型分析完成,我们就要据此考虑选择合适的算法。
基于禁手分析所需的精确度,我们在棋盘盘面搜索时,需要记录与待判断点相邻的连续黑色棋子数,并记录之后的连续空子数,并记录再之后的连续黑子数,和再之后的连续空子数,以及再之后的连续黑子数。所以可以说搜索的深度要达到5层。
在判断关键点的可下性时,选用递归的方法来判断其是否不是禁手点。
 
于是最后我们可以得出禁手判定算法的思路。
第一步:将待判断点放入黑棋子;
第二步:搜索待判断点周边棋盘;
第三步:还原棋盘;
第四步:利用搜索结果依次对各方向进行分析,判断黑棋放入后所产生的棋型是否形成长连或形成可能构成活四、冲四、活三的棋型。若形成长连,判定为禁手,返回长连禁手标识。若形成可能是活四、冲四、活三的棋型,判断关键点是否可下,若不可下,该棋型统计数加1,反之,则对下一个方向进行判断,直到各个方向分析结束。
第五步:若活四、冲四棋型的统计数大于1,返回四四禁手标识,若活三棋型的统计数大于1,返回三三禁手标识。其余情况返回非禁手标识。
源代码:

五子棋的各种禁手

test
  • JJwisper
  • JJwisper
  • 2016年09月19日 01:05
  • 673

五子棋C++源代码实现禁手

  • 2011年05月07日 09:32
  • 1.35MB
  • 下载

五子棋算法--禁手的判断

  区分是不是禁手,不能简单地看是不是走成了“三三”“四四”,而应该是这样的: 1、只要黑方下一子后,形成“连五”,那就不考虑什么禁不禁手了。 2、如果没有形成“连五”,而是形成了“长连”,就肯定是禁...
  • smelless
  • smelless
  • 2004年08月21日 21:55
  • 1913

五子棋终结者的C语言实现

  • jun2ran
  • jun2ran
  • 2009年08月06日 16:20
  • 1580

C语言+二维数组+非递归实现五子棋游戏(代码贴过来后无缩进,尽请谅解,工程完成度:100%)

规则: 1、白子为0; 2、黑子为@; 3、白子先手; 备注: 1、本程序会持续进行代码与流程的完善; #include #define N 16 void wzq_show(char ...
  • jnbbwyth
  • jnbbwyth
  • 2015年07月21日 16:23
  • 4701

五子棋的各种禁手

test
  • JJwisper
  • JJwisper
  • 2016年09月19日 01:05
  • 673

【C语言】五子棋胜负判定算法及源代码

五子棋胜负的判定,一般有一下两种算法: 1.扫描整个棋盘,分别扫描四个方向是否有5个连子。网上找了很多五子棋源码都是用此算法,这意味着每下一个棋子都要扫描一遍19×19的棋盘,复杂而且低效,代码略。 ...
  • u010049708
  • u010049708
  • 2014年02月15日 15:24
  • 3350

五子棋 (用C语言编写五子棋游戏)

game.h 文件 #ifndef __GAME_H__ #define __GAME_H__ enum OPTION { EXIT, PLAY }; #include #include ...
  • rannianzhixia
  • rannianzhixia
  • 2017年04月20日 17:56
  • 2186

五子棋游戏中判断胜负的C++源代码

今天在看《精通Windows Sockets 网络开发——基于Visual C++》(孙海民 编著,人民邮电出版社出版)这本书的时候,有一个网络五子棋游戏的实例,个人觉得除了服务器和客户端通信、管理用...
  • u013149325
  • u013149325
  • 2013年12月14日 13:54
  • 2282

五子棋 判断输赢的函数

/* 刚写了个控制台的五子棋游戏,发现判断输赢花了我不少时间,特意贴出来.如果大家有更好的方法,欢迎共享. */ //每读入一个点 //通过判断垂直,水平,主对角线,斜对角线四个方向来判断输赢 #...
  • qiaotokong
  • qiaotokong
  • 2013年08月09日 00:00
  • 2971
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:五子棋禁手判定算法
举报原因:
原因补充:

(最多只允许输入30个字)