zzwu(未名) 能看看你的程序吗?
不是要AI得,AI得100分也太少了点.我只要能判断胜负,而且效率要高.

解决方案 »

  1.   

    www.smiling.com.cn里有一个电子小组,  搜索五子棋 , 有几个不错的程序值得下载,还有不少算法
      

  2.   

    surfguy(冲浪小子) :你说的不错,以下的那一点判断四条线很方便.但是随便给我一个图,也就是说不知道那个子是最后一个,那么就要一个个推,还是比较麻烦.
      

  3.   

    cxx1997(小网虫) :
    待我找出来后公布于众,让大家来提出批评和建议.AI我也已考虑,但尚未编出程序.
      

  4.   

    to :cxx1997(小网虫) ,必吧,你在定义十链表的时候,每个节点有一个域表示下子的顺序,再用一相全局变量记住最后下的棋子的序号,这样就不会出现你所说的麻烦,还可以复盘研究。
      

  5.   

    下面介绍我的五子棋游戏中,当白子或黑子下到棋盘上,判别是否赢的过程。其实思想很简单的,就是分别统计以所下子为中心,考察沿水平、垂直、正对角线、反对角线上,依此相连的同种颜色的棋子的个数,如果其中有一个恰好为5,就赢了,否则没有赢,即使有6,也不行,但同时出现5和6时,仍为赢。说明一下,以下的函数Win(col,row,c;byte)用来检测当前下子一方是否赢,其中用到的参数意义为:
     col,row为当前所下子的行和列;
     c是所下棋子的颜色,取0和1;
      mat[i,j]是二维矩阵,i,j=0 to 20;
     未下子前,mat[i,j]都填以-1,i,j=0 to 20;
      以上矩阵中,实际下子的区域为中间部分,即:i,j=1 to 19;
     棋盘格子外加一个-1围框,是为了检测方便,实际看不到;
     nh,nv,nd,ni用于统计4个方向上依次相连的c颜色棋子的数目。Function Win(col,row,c;byte):boolean;
    var nh,nv,nd,ni,x,y:byte; 
    begin
    //以下统计水平方向的连子数:
     x:=col;                  
        nh:=1;
        while (mat[x-1,row]=c) do
         begin
          nh:=nh+1; x:=x-1;
         end;
        x:=col;
        while (mat[x+1,row]=1) do
         begin
          nh:=nh+1;  x:=x+1;
         end;
    //以下统计垂直方向的连子数:
        nv:=1;
        y:=row;
        while (mat[col,y-1]=1) do
         begin
          nv:=nv+1; y:=y-1;
         end;
        y:=r;
        while mat[col,y+1]=1 do
         begin
          nv:=nv+1;  y:=y+1;
         end;
    //以下统计正对角线方向的连子数:
        nd:=1;
        x:=col; y:=row;
        while mat[x-1,y-1]=1 do
         begin
          nd:=nd+1; x:=x-1; y:=y-1;
         end;
        x:=col; y:=row;
        while mat[x+1,y+1]=1 do
         begin
          nd:=nd+1; x:=x+1; y:=y+1;
         end;
    //以下统计反对角线方向的连子数:
        ni:=1;
        x:=col; y:=row;
        while mat[x-1,y+1]=1 do
         begin
          ni:=ni+1; x:=x-1; y:=y+1;
         end;
        x:=col; y:=row;
        while mat[x+1,y-1]=1 do
         begin
          ni:=ni+1; x:=x+1; y:=y-1;
         end;
      if (nh=5)or(nv=5)or(nd=5)or(ni=5) then Win:=true
      else Win:=false
    end;
      

  6.   

    我也写过一个五子棋软件,功能还算可以,不能悔棋
    我的判赢方法非常简单,就是将棋盘的横、竖、/、\方向各扫描一边,就是在《delphi时尚编程百例》上的方法。现在想来,此方法简单,但效率不高。
      

  7.   

    后手禁双三
    ----------------是先手禁吧,后下的人本来就很吃亏了.
    johnsonrao(johnson) 
      :你说得有道理,这样我得算法又要改进了.
      看来分不够了,大家挂个号,我以后开帖子发.
      

  8.   

    zzwu(未名):
        如果你有机器下五子棋的算法,我另开帖子给你分,:-)
        你说的有道理,他就是有活四,他看不出来,也不能怪咱.
        但三三禁手还是要的,比较烦.
        你给的那大段判断是否成连五的代码,可以是可以的,但我想你自己也觉得看得难过吧.
      

  9.   

    这种程序网上太多了,如果是编着玩玩也还凑和,如果想编好了发布,就此终止吧,我都编过网络五子棋、网络围棋、网络象棋,呵呵,都只能判断胜负,没有人工智能的,所以需要两个人联网才能下,当然还有可以一个人捉摸棋谱也比较方便的功能,需要参考的话
    www.hbpcc.net/unisoft/program.asp
      

  10.   

    to cxx1997(小网虫_L) :
    我确实编过三个初级的五子棋,一个在DOS下,一个在WINDOWS下,一个在网上的。都没有化多少时间就编好了,因为没有考虑更多的AI问题。后来,在此基础上,我考虑了AI,已有了一个较复杂的框图,但未编成程序。您如果也编好一个程序,并且也能上网的话,我们可以来对弈一翻!不知如何?您若同意,让我们来一起讨论一下‘游戏规则’和‘通信协议’。您看怎样?我想这对我们两个人改进自己的程序都会有益的,不仅仅是解决AI问题,说不定逻辑上的bug也还会找出来的。
      

  11.   

    kevin_wang(kevin神) 
       如果要判断双三等,就不简单了.当然还是没有AI复杂.
      

  12.   

    我说一个判断五子棋胜负的算法吧,请大家指教:
    1。将白子和黑子放在两个不同的数组里;
    2。chess数组中的值本身是按大小排列的,假设为从大到小,其大小是按先行后列判断;
    3。从第一个数组开始查找,如果有一个同行的元素,则判断本行是否五子相连,如果有同列的元素,则判断是否有同列的五子相连,如果有同对角线的元素,则判断是否在该线上有五子相连。
    4。如果到数组尾,则按第三条搜索下一个元素。
      

  13.   

    我有算法,需要数据库支持
    首先定义4个表
    table1,table2,table3,table4tablen 表示成n个字的情况
    比如:table2 有记录如下 
    2字的情况       成为3字的条件 (需要一个算法)  
    (1,3) ,(1,4)    (1,2),(1,5)


    。     
    当一字投下是,在table1中找可以成2字的,如果有,去掉这条纪录,然后再table2里面写纪录。如果没有在table1中找可以成2字的,则在table2里面找可以成3个子的,依次往下。当然还有一些计算啦,比如每个人都有一张表,如果成n字的条件被对方破坏,就要删掉纪录啦。该算法的优点,可扩展性强,不如双三的禁手等等。
      

  14.   

    public boolean isEnd(int t)//type
    {
    for(int i=0;i<19;i++)
    {
    for(int j=0;j<19;j++)
    {
    if(qipu[i][j].type==t){
    int m, n, count;
    for(m=i+1,n=j+1,count=1;m>=0&&n>=0&&m<19&&n<19&&qipu[m][n].type==t;m++,n++,count++);
    if(count==5)return true;
    for(m=i,n=j+1,count=1;m>=0&&n>=0&&m<19&&n<19&&qipu[m][n].type==t;n++,count++);
    if(count==5)return true;
    for(m=i+1,n=j,count=1;m>=0&&n>=0&&m<19&&n<19&&qipu[m][n].type==t;m++,count++);
    if(count==5)return true;
    for(m=i+1,n=j-1,count=1;m>=0&&n>=0&&m<19&&n<19&&qipu[m][n].type==t;m++,n--,count++);
    if(count==5)return true;
    }
    }
    }
    return false;
    }
      

  15.   

    我认为需要一些表来记录当前的信息,记录2子连上一起,3子连在一起甚至4子连在一起,同时设置标志,如果连在一起的子被封则从表中删除,每下一子都需要判断是否有胜负出现,对于黑方还应首先判断是否有禁手的出现,禁手也不多,无外是3.3 &4.4&长连,但有特殊的情况不好判断,对于不连续的3,相信各位都知道,特别是在阴线上的,会让人防不胜防,至于算法,待我试过再说吧!
      

  16.   

    五子棋的规则:http://www.renju2002.com/cn/rule.htm
    好像用程序实现会好复杂。
      

  17.   

    http://www.tz363.net/bbs/showtopic.asp?TOPIC_ID=755&Forum_ID=53是否能提供些线索
      

  18.   

    五子棋以前也考虑过,想到一个较好的算法,但由于没有电脑,也没有时间,就搁下了,既然你也在考虑这个问题,就和你说说我的思想吧。
    先定义一些记号。对于棋子的布局是要分开来考虑的,即需要一个黑棋布局F和一个白棋布局G,这里F和G都是数组。为了提高运算效率,用bit来表示信息,则F 是2×13的数组,相当于一个16×13的点阵,bit位为1的表示该位置有黑棋,无棋子和白棋都为0(G情况类似)。对于你所给的棋局数组,可以先分解出这两个布局F(1)和G(1)。
    在下面的讨论中经常要用到一种移位运算,记为“^”,F(1)^1表示将布局F(1)右移一位,即点阵图移动一格,这里我只拿一个方向来说明,实际有两个基本方向的移位操作。还有点阵图的位与运算,用“&”表示;位或运算用“|”表示,位异或运算用“*”表示。
    根据以上记号和算法,我们定义F(2) = F(1)^1 & F(1),大家想一下,就可以明白,F(2)是连2的点阵图。用同样的方法,我们定义F(3) = F(2)^1 & F(1),F(4) = F(3)^1 & F(1),F(5) =… F(9)。有了这些,就可以判断棋局的输赢了。只要G(5)、G(6)、G(7)、G(8)、G(9)不为全0就白赢了,黑棋连6算输,可以用点阵图F(5)^1& F(6)来判断,这也是禁手的判断方法。这里我只说明了一个方向,实际有4个方向,可以由定义的两个基本移位操作实现。对于双连三,要从几个方向的点阵图来考虑,.它的判断要特殊处理。
    如果要考虑AI,上面过程中的F(3)、F(4)等也是有利用价值的。这种棋类程序最主要的就是对棋局的评价函数,一个好的评价函数不应该只考虑连5的情形,还应该考虑一些中间情形,可以称之为“棋筋”。通常的棋筋有如下几种:(●为黑子;○为白子;□为空)
    ●● ;   ●●●;  ●●●●;  ●●□●;  ●□●●; ●□●□●; ●□●●●; ●●●□●。
    我们只要计算各种棋筋的总数,并加权求和,就可以此为评价函数,并且应该是个较优的评价函数。但怎么去算,我拿第四种做例子来说明。先计算点阵图F(2)^2 & F(1),很显然,这个点阵图就是该棋筋的布局,统计该布局中位为1的数目,就可以得到该棋筋的数目。其它棋筋用同样的方法也可以求得。
    但是,应该考虑无效和减效的棋筋,例如黑连4两边有白棋(○●●●●或●●●●○.),这种棋筋的布局点阵图为F(4) ^ 1 & ( G(1)^5 * G(1) )。根据这一思想,可以列出无效的棋筋,并求其数目,最后的评价函数要减去这些棋筋的效果。
    在搜索过程中,我们不必计算每一布局的评价函数,只计算下这一子带来的评价函数的增加值即可。这可以用这一子的点阵图H(只有一位为1,其余为0)与各种棋筋布局点阵图做相应运算,例如统计点阵图H & F(2)^1中1的位数,可以得到原图中连2升为连3的数目,双连3也由此判断。
    今天就写到此吧,有点事要走。
      

  19.   

    我认为有两个方法:
      法一:
        我曾经也用C语言编过,我认为刚才那西算法都很有用,但我还有一个意见,我们可以这样想,我们把这个问题转化为纯数学问题,我们求一条线的斜率:
        1.当其=45度时表示斜着相连(不管是至左下向右上,还是右下向左上,都连成一条直线)。
        2.当斜率=0时表示横着相连,或竖着相连。
       当然既然是五子棋,棋的数量开始要限定。
      法二:
        大家都学过《数据结构》,我们可以用堆栈的方法,类似于找方向,一共有8个方向(东,南,西,北,东北,东南,西北,西南),我们分别向不同的方向找和开始第一个相同的符号(如*),若果相同,压入栈,再找,如果不相同,则判断该方向不通,意味着没有5个相同的符号,就没有连成五子。类似依次找齐8个方向。就OK了。    代码部分未写,只提供了算法的思路!!!!请谅解!!!
      

  20.   

    mty(天鱼):你的算法我看了之后感觉和zzwu(未名) 代码是同一种思路,只是用C++优化之后,代码行少多了,但可读性也差了点。jack4liang(菜):你的思路不错,但如何利用这四张表,确实有些难度。 我正在考虑你的想法。 libi():你的解法和zzwu(未名)是一样的,但“F(1)^1表示将布局F(1)右移一位”这样判断一点上是否有子,确实更加容易理解。同时指出一点问题:你这样需要8个方向,你难道用8个函数F(1),H(1)。来表示吗?如果是,那么就和zzwu(未名)做法一样了。非常不好控制。ronaldo17() :你的法一,使我想起三角函数,或者向量法,我要考虑考虑。
                  法二:和其他人做法其实是一样的。
      

  21.   

    surfguy(冲浪小子):你说要记录下棋的次序,看来也有必要。不过好象没有多大用处。 Hyphoon(间接点球),peachblossom(桃花仙子) :感谢两位。下面建议讨论两个方向:一:如何不要一个方向一个方向地搜索,也就是说用一个函数就能处理(不要CASE)。可以考虑一下向量。
        二:活三的判断。(其实包含了活二,活四)所谓活三,和五子连珠不同,三个子中间只有一个空格也算,而且两端都要有空格才能算。好象如果空间只够放五个那么已经有三个,也不算的。我准备结贴后作成FAQ,大家还有信誉分拿,呵呵,比专家分还难拿哦。
      

  22.   

    当今五子棋软件最强棋力的当属:黑石(blackstone)俄国人的作品
    比较知名的还有:renju2002和……(抱歉,一时想不起来了)
    国人作品中fiver6的最好,据专业人士分析(去年的消息),黑石(blackstone)是具有职业水准的,fiver6的棋力在renju后面,估计可以排世界第三。
    我经常在联众下五子棋的,所以多补充一些:
    1、最简单的五子棋规则就是无禁手
    2、有禁手时包括:三手交换(下到第三手执白方可以选择交换棋子,即换成黑子)
                    五手两打(第5手时黑方可选择两点下,白方可以去掉自己不 
                             想要的点)
      走禁手就输,6子,双三,双四等
    3、五子棋的开局
        由于五子棋的开局有必胜、必败、黑优、黑白均衡等的区分(只在禁手情况下,因为无禁手黑必胜)
    花月局 
    蒲月局 
    水月局 
    明星局 
    瑞星局 
    名月局 
    金星局 
    寒星局 
    恒星局 
    银月局 
    峡月局 
    残月局 
    山月局 
    新月局 
    岚月局 
    松月局 
    溪月局 
    疏星局
    长星局 
    彗星局 
    雨月局 
    丘月局
    斜月局
    妖刀局
     
    所以,如果设计中的软件需要对开局作出判断
      

  23.   

    以下有一篇文章可以参考以下
    国际象棋中有以兵为参照,设兵为1,马象3。5,车5。5,后10
       同样中国象棋中也有马和炮等于车。
       那么五子棋是不是也可以用数学的模式来表示呢?
       我初步的构想是
       眠一 1
       活一 1。5  ,  2
       眠二 3     ,   4,   5
       活二 7     ,   8,   9
       眠三 10    ,   12,  13
       活三 20
       先手 10-15
    那么为什么同样是活一会有1。5和2之分呢。请看下图   
    在竖线上A图的黑子活一与B图的价值是不同的,因此A图黑子
    为1。5,B图的黑子为2。
         15┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓ 
         14┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
         13┠┼○┼┼┼┼┼┼┼┼┼┼┼┨ 
         12┠┼┼+┼┼┼┼┼┼┼+┼┼┨ 
         11┠┼●┼┼●┼┼┼┼┼┼┼┼┨ 
         10┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          9┠┼A ┼┼B ┼┼┼┼┼┼┼┼┨ 
          8┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          7┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          6┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          5┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          4┠┼┼+┼┼┼┼┼┼┼+┼┼┨ 
          3┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          2┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          1┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛
           ABCDEFGHIJKLMNO
    同理可得眠二的不同价值:
    C为3,D为4,E为5
         15┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓ 
         14┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
         13┠┼○┼┼○┼┼○┼┼┼┼┼┨ 
         12┠┼●+┼●┼┼●┼┼+┼┼┨ 
         11┠┼●┼┼┼┼┼┼┼┼┼┼┼┨ 
         10┠┼┼┼┼●┼┼┼┼┼┼┼┼┨ 
          9┠┼┼┼┼┼┼┼●┼┼┼┼┼┨ 
          8┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          7┠┼C ┼┼D ┼┼E ┼┼┼┼┼┨ 
          6┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          5┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          4┠┼┼+┼┼┼┼┼┼┼+┼┼┨ 
          3┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          2┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          1┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛
           ABCDEFGHIJKLMNO
    那么眠三的价值就是:
    F为10,G为12,H为13
         15┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓ 
         14┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
         13┠┼○┼┼○┼┼○┼┼┼┼┼┨ 
         12┠┼●+┼●┼┼●┼┼+┼┼┨ 
         11┠┼●┼┼┼┼┼┼┼┼┼┼┼┨ 
         10┠┼●┼┼●┼┼┼┼┼┼┼┼┨ 
          9┠┼┼┼┼●┼┼●┼┼┼┼┼┨ 
          8┠┼┼┼┼┼┼┼●┼┼┼┼┼┨ 
          7┠┼F ┼┼G ┼┼H ┼┼┼┼┼┨ 
          6┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          5┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          4┠┼┼+┼┼┼┼┼┼┼+┼┼┨ 
          3┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          2┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          1┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛
           ABCDEFGHIJKLMNO
    我们可以用数学的模式来分析一个开局,暂时就用我这个不完尚的数字
    来分析一下瑞星的定式
         15┏┯┯┯┯┯┯┯┯┯┯┯┯┯┓ 
         14┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
         13┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
         12┠┼┼+┼┼┼┼┼┼┼+┼┼┨ 
         11┠┼┼┼┼┼┼┼┼●┼┼┼┼┨ 
         10┠┼┼┼┼┼┼┼○┼┼┼┼┼┨ 
          9┠┼┼┼┼┼●○○C ┼┼┼┼┨ 
          8┠┼┼┼┼┼○●●┼┼┼┼┼┨ 
          7┠┼┼┼┼┼┼┼○┼B ┼┼┼┨ 
          6┠┼┼┼┼┼A ●●┼┼┼┼┼┨ 
          5┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          4┠┼┼+┼┼┼┼┼┼┼+┼┼┨ 
          3┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          2┠┼┼┼┼┼┼┼┼┼┼┼┼┼┨ 
          1┗┷┷┷┷┷┷┷┷┷┷┷┷┷┛
           ABCDEFGHIJKLMNO
    现在白棋的子力价值是多少呢:10+6+9.5+7=32.5
    一个眠三10,两个眠二3*2=6,
    四个真活的,(注意,象I10这个子算两个活一,因为在横线和斜线上都有活)
    一个半活G8子   价值是4*2+1.5=9.5
    七个眠一 1*7=7黑子的价值是:8+10+14+1.5+6=38.5
    一个活二 7 
    三个眠二 10
    七个活一 14
    一个半活 1.5
    六个眠一 6此时白先手,则有ABC三个价值较高的点。
    A点的价值是:11
    挡了黑棋一个活二变眠二,一个活一变半活一,4+0.5 
    自己成了一个眠二,一个活一,一个半活一,  4+2+0.5
    B点的价值是:14
    成了两个活二
    C点的价值是:12
    挡了黑的活一变眠一   1
    眠二变成眠三,活一成活二  7+5      先手的价值应该是一个变化的范围,超出了这个范围,就是走出好棋。
    反之刚为坏棋,还有就是在变化范围内的是正常手。当然,这个数值只是我个人的想法,是很不完尚,我这只是抛砖引玉,
    希望能有人给出精确的数值。棋当然也不是用数字可以表达的,但是
    在某一个方面却能说明。
      

  24.   

    此外,在软件的设计中最好要考虑五子棋的定式,加入定式库后的软件,在开局后可以很好的取得优势,
    在当今的软件中,五子棋大师2据说是配备了大量的定式库的,而颇受好评的fiver6则没有,它有时侯甚至会开黑必败的彗星和游星局,这很是麻烦!