CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

我想寻求五子棋的简单算法!!

楼主snoopy291(稻草)2005-05-03 22:27:07 在 C/C++ / C++ 语言 提问

有谁知道比较简单点的算法?  
  我不知道该怎么去找最重要的那点,怎么比较棋盘上最重要的点。  
  我现在烦恼了好几天,写来写去结果计算机很容易输.  
  我现在发现自己写程序的话是写不出来的,  
  毕业设计我不知道该怎么办才好了  
  能有点提示吗??  
   
  问题点数:100、回复次数:39Top

1 楼snoopy291(稻草)回复于 2005-05-03 22:36:06 得分 0

有些人的论文是抄书或搬网上的,我坚持自己做,但觉得自己太固执了。  
  根本做不出,技术不高.  
  算法也不会.  
   
  很想有高手的提示,比较简单的算法就好.Top

2 楼sun428(Born to Win)回复于 2005-05-03 22:43:39 得分 0

去google吧Top

3 楼snoopy291(稻草)回复于 2005-05-03 22:53:08 得分 0

我搜索过了,看来我问这个问题没有多大的意义的呢.  
  不过那些算法对我来说,我还觉得挺复杂的,又难懂.  
  所以我想找很简单的.  
  我现在写的出的一个五子棋程序实在是太简单了,  
  而且计算机是乱下了,从一开始就是从第一列开始下,不管人下了多少要赢了,  
  计算机还是对人下的棋子无动于衷,一列一列地下的.  
  ^_^真是郁闷.  
  好希望能过关.  
  Top

4 楼ldwh(灰沙)回复于 2005-05-03 22:58:51 得分 0

我有个例子,不是我写的Top

5 楼snoopy291(稻草)回复于 2005-05-03 23:07:04 得分 0

你的例子简单吗?  
  那些网上的什么冲三活四,死四之类的名词我好难理解的.  
  不知道是什么样的棋型才是,那都是涉及到专业术语,  
  可是我的老师说不要去理解那些也可以的。  
  :(  
  快要崩溃了,每天都在想.做不出  
  放完假就要答辩了,我好急Top

6 楼ldwh(灰沙)回复于 2005-05-03 23:20:32 得分 0

没有说明,只有代码  
  Top

7 楼snoopy291(稻草)回复于 2005-05-04 11:38:39 得分 0

没有说明的代码肯定很难看得懂,我也搜索到,但因为没有注释,我看不下去了,  
  我现在还在自己做.就坚持下去吧,就算做不出,起码也学到了好多东西.  
  ^_^  
  实在到逼不得已的那天,我再看.^_^Top

8 楼lw1a2(一刀 现在改六点下班了:()回复于 2005-05-04 11:42:42 得分 0

不是吧,你连五子棋的那些术语都不懂,却要做五子棋的算法?Top

9 楼snoopy291(稻草)回复于 2005-05-04 12:12:09 得分 0

老师都说可以不用去理解了。  
  我懂得下一点棋啊,那是我的毕业设计论文的题目。  
  我现在都不知道当时怎么选了这个题目.  
  我确实是不懂冲三活四和死四,但我懂只要能连成五个就赢.  
  ^_^Top

10 楼snoopy291(稻草)回复于 2005-05-04 12:15:15 得分 0

要是有谁懂的话,可以告诉我吗?至少可以了解一下.Top

11 楼kulongus(公司会计说:零钱太少了,你还是半年领一次工资吧)回复于 2005-05-04 13:50:13 得分 0

郁闷,我也是做五子棋  
  Top

12 楼diandian82(点点(nothing))回复于 2005-05-04 14:06:57 得分 0

如果要让计算机会下棋那真的不简单啊,要用到些人工智能的东西!可惜我不会,帮不了你啊!Top

13 楼learner_baker(菜鸟看世界)回复于 2005-05-04 14:24:51 得分 30

设定三个数组,一个记录棋盘位置的代码,一个记录电脑下子的代码,一个记录人下子的代码。(如:0代表电脑,1代表人),通过循环扫描两个记录下子代码的表去查找你上面所说的活三,冲四等。。只要扫描到符合条件的就是胜利者了。我做过。这只是我的课程设计。如果想人机对战的电脑聪明点,多遍历几次数组,查找最适合的位置就行了。网上有很多这样的例子,你最好用自己的方法去实现。。毕竟算法很多,而且都是人想出来的。好好干吧。Top

14 楼snoopy291(稻草)回复于 2005-05-04 15:00:26 得分 0

呵呵,谢谢楼上,我也是自己想的,但好象都是凭下棋的一点经验的,所谓冲三活四死四死三那些我不知道是什么东西。我也很想了解,但我没有看到游戏里有关的定义到底是如何的。  
  在加油了。   也许不是很强,起码也能下一点吧.  
   
  我该去哪里了解活三冲四这些术语啊?Top

15 楼SaiRose(Learning......)回复于 2005-05-04 15:46:01 得分 0

有时间自己找找人工智能方面的资料吧  
  网上的带AI的程序也很多  
  www.vcok.com看看去  
  感觉带AI的都有点烦的也不是一两句能说清的  
  关键就是求当前棋盘上每个点的权值(叫法不记得了)  
  然后选最大的  
  楼主最好能问个下的很好的人  
  那样就容易知道下哪些点最可能赢,然后相应的应用到程序上Top

16 楼snoopy291(稻草)回复于 2005-05-04 15:58:32 得分 0

呵呵,我现在做出一点了,是凭经验做的,还没有用到人工智能,所以当我和它下的时候还是有胜它的情况的,所以就觉得情况不全面,要是去看书时间已经来不及了。我现在就想知道那些所谓冲三活四到底是什么东西,然后我把所有可能最会胜的情况都搜索.  
  但我还是觉得自己做的太简单了。人机对弈计算机聪明的话,是不会轻易让人战胜的吧?  
  我下的就有好几次还是赢了计算机.AI对我来说也是挺深奥的东西,所以只能采取简单的做法了,因为时间的关系我真的来不及了。Top

17 楼snoopy291(稻草)回复于 2005-05-04 16:02:49 得分 0

SaiRose(Learning......),你给的网站很不错,有好多知识和东西,谢谢你!!  
  激发我学习的兴趣了。^_^Top

18 楼snoopy291(稻草)回复于 2005-05-04 16:32:04 得分 0

不过,我现在的算法是太过简单了:先搜索连续成线的棋子数最多的,并且两边都各至少有一个空位,然后就选择这点下,但每一次搜索只考虑了一个点的一个方向,所以当出现两个方向都能连成五子连边也有空位的时候,计算机没有及时防守,所以失手了。^_^我现在还在想怎么去补充.  
  如果不补充还可以勉强上交吧,那可是个置命的弱点.:(  
  我就是不知道该怎么搜索多个方向都有连续子,特别是有不止一个空格的情况,而且重要程度如何,该放在哪里也不知道.我的程序是按照顺序下来的,前面的条件不满足就到下面的.连续棋子数越多的先放在前面,后面就是依次减少的。Top

19 楼corrupt(喜欢 睡在床板下 的思考)回复于 2005-05-04 20:22:57 得分 0

呵呵,   搞个人-人对战的不就可以了,Top

20 楼snoopy291(稻草)回复于 2005-05-05 01:23:51 得分 0

呵呵,人人对战那不是只需判断胜负就可以了吗?  
  要弄联机的话,恐怕更难吧.  
  My   God.  
  我担心论文不过关.  
  程序运行不按照程序的去做,真不知道为什么.Top

21 楼km3(北落师门)回复于 2005-05-05 08:33:07 得分 30

楼主想做五子棋方面的程序,还不懂得规则,想做好的话不太可能。我建议你先到google里搜一下,  
  五子棋的规则,好好看一看。然后到联众里去下两天五子棋。  
   
  我以前拿delphi写过一个,算法的效率有点低下,不过电脑的AI可不菜,可惜电脑升级的时候不小心  
  硬盘上的东东全没了。  
   
  我说一下我的思路(我自己想的,可不是网上搜的),用一个二维数组(array1)来记录当前棋盘上的  
  情况(如:空0,黑1,白2)。再用一个二维数组(array2)来预测array1中的一个0变为1或2的情况。  
  在写N多个方法遍历数组来了解棋局的情况,返回int型,如一个方法来判断五连的个数,再有个方法来  
  判断冲四(冲四有多种情况:20222,22022,22202,2222)的个数,…………,这样方法越多越详细,电脑对棋局情况了解的越详细,电脑的AI越高。每一回电脑下棋的时候array1里的一个0变为1放到array2里,然后用你的N个方法去遍历,每个方法的返回值都乘个分数,比如五连的方法的返回值*30000,冲四的返回值*1000,当然也可以几个方法和在一起用来判断四三子类的棋局,然后你还点判断这个0变为2的情况,也可以得出一系列的分值,将这些分加在一起,就可以得出这点的分值了,将array1里的每一个0的分值都算出来,然后得出分值最高的一点,就是电脑要走的棋了。  
   
  你也可以建array3,array4…………的数组来预测以后2,3…………步的棋局.  
   
  我这么写效率有点低,不过可以判断禁手,我在网上看到的例子都是没有禁手的。  
  Top

22 楼SaiRose(Learning......)回复于 2005-05-05 11:03:58 得分 0

楼上的哥们是不是喜欢天文...  
  Top

23 楼graciexy(在程序的海洋里学游泳)回复于 2005-05-05 12:03:24 得分 0

是的,我学长做过这个课题,也是算横竖还有对角线上的权值(还是概率)大小的。Top

24 楼snoopy291(稻草)回复于 2005-05-05 13:00:58 得分 0

谢谢楼上km3(北落师门)给的思路!!还有learner_baker(菜鸟看世界)的思路!!  
   
  不过我现在做的却是只有一个数组存储棋盘的情况.然后等人每下一子之后就对当前的棋盘二维数组进行遍历,对每一个空位,  
  1.要是遇到计算机马上会赢的,即这个空位有连续四子的情况,则先下,  
  2.若第1条情况没有,若此空位是人马上会赢的位置,则下,阻止其胜利,  
  3.若前2条情况没有,就看这空位对计算机来说有没有活三的情况,若有(可以构成活四或冲四),则下,以进攻  
  4.若前3条情况没有,就看这空位对人来说是不是有活三的情况,则下,以防守  
  5.若前4条情况也没有,就看对计算机来说是不是有连续两子的情况,若有(可以构成活三),则下,继续进攻  
  6.要是前5条都没有,则看对人来说有没有连续两子的情况,若有,则下,也是为及早防守  
  7.要是前面的情况都没有,则看对计算机来说若有一子,空位可以和它构成两子的,则下,继续进攻.  
  8.要是还没有,则看人方,人要是有一子,空位可以和它连成两子,以防守.  
   
  每次都是人下子后,计算机都按照顺序遍历一遍,若是在第一条找到符合的空为,则下,然后轮到人下,人下后,计算机又重新遍历,要是第一条没有符合,又重新遍历,找找看有没有符合第2条,要是没有,又重新遍历,找符合第3条的,这样继续下去,直到找到其中一个符合的就下。上面的顺序我就认为是按重要程度来下了。  
   
  我的想发就这样,但我下了之后,计算机很容易输,因为我没有考虑一个空位上的多个方向一起结合,  
  只考虑一个方向.所以遇到双三,四四的时候,计算机没有办法识别,所以输了。可是我不知道怎么改进了。没有时间了,我的对话框还是有问题的,我画棋盘是在Onpain()函数里用.MoveTo()和LineTo();  
  画棋子是以TextOut()来输出不同的符号,比如"+"表示计算机下的棋子,"-"表示人下的棋子.  
   
  但这样做出来的对话框很奇怪,下棋之后的字符,要是我动了这个对话框以外的程序窗口或者什么,那些字符全都不见了!要是我猛地拖动对话框,上面下的字符全都不见了,好奇怪!!我都不知道原因,我传给别人下下看,别人一点击一下,字符马上消失!!  
   
  我好郁闷,不知道哪里出原因,算法不够聪明这不用说了,对话框出现这样的情况真是不可理解.  
  难道一定要用画图或粘贴图上去的,我都不会用.  
   
  我的知识水平太有限了!!!不知道该怎么解决.只勉强做到这一步.     :(Top

25 楼snoopy291(稻草)回复于 2005-05-05 13:29:36 得分 0

而且,计算机有时候还没有按照上面的顺序来下的,明明有满足第四条的,它却执行第六条的.所以在该下的地方,计算机还什么样下,人就抓住了这一漏洞,计算机输了.但我的程序我还没有仔细查找过,但觉得程序不会这么出错的吧,就是按照顺序写下来的,满足条件的先执行不是吗?可是它却不这样.    
   
  有哪个高手清楚的话,或有什么想法,请提出,请指教.  
  分享一下你们的高见.  
  ^_^Top

26 楼snoopy291(稻草)回复于 2005-05-05 13:38:53 得分 0

在前面的两位高手给出思路之前我已经这么做了。  
  我不知道我这样是否能合格了。  
  突然觉得什么都不知道了.  
  什么都不懂.:(  
  Top

27 楼SaiRose(Learning......)回复于 2005-05-05 14:23:19 得分 0

km3(北落师门)   已经说明的很清楚了  
  我觉得楼主没有理解他的意思  
  哪个点的重要程度当然可以按楼主那么说的判断,但我觉得很难全不考虑  
  而且很麻烦,太多判断语句  
  比较好的就是按   km3(北落师门)   的计算当前棋盘上的每个点的重要程度  
  用一个值来衡量,然后每次下这个值最大的那个点  
   
  另你说的画图的问题是 你没把棋子的位子保存下来  
  你是用数组来表示棋子的吧,0-没下 1-白 2-黑,是么?  
  那么在OnPaint函数里写画图程序时就按你的这个数组来画棋子  
  数组哪个位子上值不为0则相应的画上白或者黑  
  windows程序是在每次重绘窗口时调用OnPaint函数  
  只要你在OnPaint里都画了就不会出现你说的情况Top

28 楼SaiRose(Learning......)回复于 2005-05-05 14:25:51 得分 0

画棋子可以不用TextOut来画  
  就直接CDC.Ellicpse()就可以了,画圆  
  不过不同颜色的话还要加上不同的画刷  
  如果还想好看点就用位图了,就看楼主有没这个时间了  
  呵呵,加油了Top

29 楼snoopy291(稻草)回复于 2005-05-05 16:14:42 得分 0

SaiRose(Learning......),你说得很对!!可是你怎么知道我是这样表示的呢?  
  我确实是用数组来表示棋子的,0-没下 1-白 2-黑,  
  按km3(北落师门)的算法,好象我没有用我的算法之前试过,但因为出错,我不用了,我还以为是算法的问题.因为每次调试的时候,箭头都指向条件句,可能我的条件句也是太复杂了。那时候我用调用函数的方法,后来发现调用屡屡出错,索性直接不用调用了,就用最笨的办法,干脆一个一个来好了。  
  因为这样做的时候,我没有出错.之前一点击鼠标就是弹出一个对话框说XX.exe遇到问题要关闭,表示抱歉.用了最笨的方法后,这个问题不出现才得以解决,我现在也想不通自己的程序错在哪里.  
   
  但有一点,对km3(北落师门)的计算方法,我不是很明白,也许先按我这个笨方法写一下吧,完之后要是还有时间可以修改,我会尝试他的算法看看.他说的那个用一个方法来判断五连的情况,是说用一个函数来专门判断五连的,再有,用另一个函数来专门判断活四的,....,是这样吧,就是说一个空位,可能四个方向都各有一种棋型,每种棋型都有一个返回值,就把那个空位的四个方向的四个棋型对应值加起来,是这样吗?然后也计算这空位的若下的是另一方的,也计算一下,然后所有的点都有一个值,比较找最大的.是这样吧?   我曾经用过,可能是我程序错误而没有得到实现吧,后来就放弃了。  
   
  要是有时间我考虑用位图吧,这我还得自己去看点书.  
  但我有很多困惑的地方,看书的时候,好多地方出现什么CClientDC和CCpaintDC和  
  什么CDC,GetClientDC,我好混淆这些地方的.有时候也看到逻辑坐标和屏幕坐标之分,我都不知道它到底指什么,还有什么获取窗口客户区之类的,设备上下文到底和窗口、窗口客户区有什么区别?  
   
  CDC.Ellicpse()不是只能画椭圆吗?我该到底怎么画一个实心圆,有颜色的,但我不会用那些函数,到底用什么类的什么对象我也不知道,要是你知道能给个例子吗?  
   
  还有要是我没有用位图,就像我用的TextOut(),如果要保存到底该怎么保存?  
  棋盘纵横线我是在OnPaint里画的,你的意思是说,我画棋子即TextOut()也要放在OnPaint()里?  
  可是一个OnPaint()函数怎么知道我要画哪方的棋子啊?  
   
  ....好多问题冒出来了...  
   
  还有执行文件的问题,我当时建立项目时,只是选择了基本对话框那一项,其它的都是默认的。  
  但当我想把执行文件独立脱离VC环境运行,我不知道该怎么弄,别人告诉我说要设置成静态编译,但我用之后,拿到别人的没有VC的机子上运行却出现状况:说没有找到MFC42D.DLL文件,所以应用程序未能启动.重新安装应用程序可能会修复此问题.    
   
  不知道是不是我安装VC不完全还是怎么样。  
   
  而且我的五子棋很不正规,棋子是画在格子而不是直线上,还是用不同的字符表示的。呵呵    
  今天按上面说的去搜索看了冲三活四的说法,现在才知道六个子连的时候不算胜,而我的那个程序连成六个也算五连在里面了,所以也算胜利。呵呵,觉得自己很搞笑,都没有想那么多呢。  
   
  觉得游戏里的规则还挺多的,我还没有用禁手,也没有到高级中级的程度,也没有悔棋的步骤,  
  那样更加复杂了。我只想能下一般的棋计算机不容易输就好了。  
  我们老师要求还没有那么复杂,但计算机容易输说明算法有漏洞。  
   
  ^_^   谢谢你!!!!Top

30 楼snoopy291(稻草)回复于 2005-05-05 16:25:51 得分 0

对了,我画棋子的函数都放在Onpaint()外面的.  
  但也没有在Onpaint()里面调用它们.我应该怎么做才能保存啊?  
  要放到里面去吗?也许我该多加一参数表示是哪方的.Top

31 楼snoopy291(稻草)回复于 2005-05-05 16:47:39 得分 0

哦,现在我想起来:  
  画两种棋子,我该怎么放到Onpaint()里啊,  
  我的画棋函数在Onpaint()外面定义是这样的:  
  DrawManChess(int   i,   int   j)  
  DrawPcChess(int   i,   int   j)  
  只要我该下在(i,j)的时候,我就调用它们,但我想,这样的函数放在Onpaint()里怎么区分怎么调用,而且参数该怎么传递啊?  
  我是用自定义的ChooseBestChess()选择要下的位置.在ChooseBestChess()里调用画棋的函数,但画棋的函数又要放到Onpaint()里面去的话,参数到底该怎么写啊?  
  哎,好乱哦Top

32 楼dzw2004(深蓝)回复于 2005-05-05 16:49:14 得分 0

up~Top

33 楼SaiRose(Learning......)回复于 2005-05-05 16:52:40 得分 40

不知道你还有多少时间,本来以前我就一直准备做一个五子棋的  
  不过当时很菜,是用tc编的,功能也只有判断输赢  
  这段时间准备一个课程设计,等做完了就准备做个五子棋的,作为最后的一个程序(然后就准备考研了,呵呵,准备痛苦了,不能继续学习program了)  
  如果你的时间允许,也许过几天(1星期内)可以一起探讨了.  
  关于算法,我断断续续的想过一点,说下,不知道好不好实现:  
  就是关于求最大权值的方法,举个例  
  先说明下,你另用一个2维数组保存每个点的权值  
   
  000  左边这表示下了一个白棋,它的周围都没下,那么可以将下了棋的那个点位子的权值设  
  010  为0,而它周围8个都设为10(这个自己定)   
  000  
   
  0000 左边表示下了2个连在一起的白棋,再次设置时就将a位置的点的权值设为100(这个  
  a11a  也是自己定,但记住一定要比10+10大,为什么自己先想想)  
  0000  
   
  其他的类似了,每下一步棋就要将当前棋盘上的点的全部权值都扫描一遍,将需要改的权值都改了  
  这只是个基本的想法,实际实现时要考虑的还有很多  
  你有空先想想,我自己想的,也不知道对不对  
  最好可以下下五子棋,那样的话认识会提高的(我选五子棋就因为我自己蛮强,呵呵)  
   
  关于画图,那只是个架子,不要在那上面花时间,我一直认为程序的好坏是用你所用到的算法和数  
  据结构来评价,所以看到那些用华丽的界面来掩饰幼稚的算法的程序就很鄙视  
  鉴于你说的情况,你可以找本vc的书看看,市面上很多的,图书馆也应该有,很多都是手把手教你  
  怎么做的,你所需要知道就是对程序运行的基本了解,比如什么时候窗口重绘,什么时候调用什么  
  消息,知道这些就够了,你现在也没时间了解更多的,用MFC做个架子没你想像的那么复杂  
  MFC我了解的也不多,我是从SDK开始看的  
  你画棋子也要在OnPaint里画!!!记住,这是肯定的  
  也很简单,就把你以前怎么画的程序搬到OnPaint里来就可以了  
  画圆的函数我不记得了,你查查,应该很容易找到的  
  你所说的运行时弹出一个对话框说XX.exe遇到问题要关闭估计是数组越界了,仔细检查吧Top

34 楼SaiRose(Learning......)回复于 2005-05-05 16:54:44 得分 0

直接把函数放进去不就可以了么?Top

35 楼snoopy291(稻草)回复于 2005-05-05 17:25:38 得分 0

呵呵,谢谢你!!  
  我全都明白!!  
  你这么忙还这么耐心地解说.  
  有空我会想!!如果我不是放完假答辩,也许和你会同步的.  
  呵呵.  
  ^_^  
  我们继续努力吧!!Top

36 楼snoopy291(稻草)回复于 2005-05-05 17:28:20 得分 0

说的也是,我觉得我的界面挺简单朴素的.但就是很怪,字符会无影无踪地消失,我现在听了你的解说,真的明白了!!我会改进!棋子下在格子里也没有问题吧?虽然现在都是下在直线上的。  
  但我想简单点.就像你说的,最主要体现算法和数据结构吧.  
  ^_^Top

37 楼SaiRose(Learning......)回复于 2005-05-05 18:15:20 得分 0

呵呵  
  补充一下,也不能说的那么绝对,毕竟和用户打交道的还是界面  
  所以一个好的界面也是很重要的Top

38 楼snoopy291(稻草)回复于 2005-05-05 20:35:33 得分 0

^_^  
  先完成最本质的东西,如果时间允许,再完成外在的东西.  
  还是挺感激你的!!Top

39 楼snoopy291(稻草)回复于 2005-05-12 20:05:54 得分 0

今天答辩了,我都不知道怎么回答问题,很多问题我回答起来都是牛头不对马嘴的.  
  …………  
  我结帖了,感谢以上各位的热心帮助!!  
  ^_^Top

相关问题

  • 连珠五子棋的算法
  • 关于五子棋的算法。
  • 怎样实现五子棋的算法
  • 征求五子棋高难度算法?
  • 五子棋算法!!谁有,急!!
  • 简单问题,寻求更好算法?
  • 各位大侠,救助搜索法五子棋算法
  • 谁有五子棋的核心算法?(C)
  • 谁愿与我探讨一翻“五子棋”的算法
  • 求五子棋的高级的算法??悬赏...!!!

关键词

  • 算法
  • 函数
  • 计算机
  • 字符
  • 数组
  • 棋子
  • 五子棋
  • 空位
  • 遍历
  • onpaint

得分解答快速导航

  • 帖主:snoopy291
  • learner_baker
  • km3
  • SaiRose

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo