为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

电脑围棋程序编写思路

2017-10-28 13页 doc 82KB 23阅读

用户头像

is_633423

暂无简介

举报
电脑围棋程序编写思路电脑围棋程序编写思路 荷蒲 wq.hepu.cn 荷蒲围棋软件的编写思路。 在围棋程序的实现中,较为关键的是围棋电子棋盘的设计。其他所有功能都是围绕围棋 电子棋盘展开的。电子围棋盘的核心是围棋棋盘的数据描述。 1、首先定义围棋子信息: #define EDGE 23 //棋盘最大格数 #define MAXMM 500 //最大手数 //color表示棋子颜色,x,y表示在棋盘上的坐标 //num表示下子的顺序。=0表示提前摆放的子。 //zt 表示棋子状态 //qs 表示棋子的气数 //sm 表示有说明...
电脑围棋程序编写思路
电脑围棋程序编写思路 荷蒲 wq.hepu.cn 荷蒲围棋软件的编写思路。 在围棋程序的实现中,较为关键的是围棋电子棋盘的。其他所有功能都是围绕围棋 电子棋盘展开的。电子围棋盘的核心是围棋棋盘的数据描述。 1、首先定义围棋子信息: #define EDGE 23 //棋盘最大格数 #define MAXMM 500 //最大手数 //color示棋子颜色,x,y表示在棋盘上的坐标 //num表示下子的顺序。=0表示提前摆放的子。 //zt 表示棋子状态 //qs 表示棋子的气数 //sm 表示有说明信息 typedef struct qizi { int color,x,y,num,zt,qs,sm; } qizi; qizi qipu[MAXMM]; //棋谱信息 qizi qipan[EDGE][EDGE]; //棋盘信息 2、紧接着要考虑的是下棋相关信息。 int nk=0; //显示棋子序号,nk=2显示序号,1=气数 int BoardLines=19; //棋盘线数,默认19 bool ComputerPlaying; //1=该计算机下 0=人下 bool Computerp1=0; //1=计算机下黑 0=人下 bool Computerp2=0; //1=计算机下白 0=人下 int PlayType=0; //2=人-人,1=人-计算机,13=人-网络,0=没有开始,-1=删除棋盘上死子,-2=暂停,3=布黑子,4=布白子,9=演示,11=学习 int PlayType1=0; //2=人-人,1=人-计算机,13=人-网络,0=没有开始,-1=删除棋盘上 -2=暂停,3=布黑子,4=布白子,11=学习 死子, int MoveCount,MoveCount1; //计步器,记录落子手数,自然顺序 int Playnum=0,Playnum1=0; //要标识的围棋手数,下棋顺序 int CurrentX; //记录热子X坐标, int CurrentY; //记录热子Y坐标 char CurrentWho; //记录当前棋子颜色,0=黑 1=白 2=空(终局等,待写) char CurrentWho1; //备份上一次CurrentWho int timew=0,timeb=0; //计时器设定数据 int sdy1=0,sdy2=0; //学习功能上使用 int gz; //规则0=中国规则,1=日本规则,2=应氏规则 bool plays1=true; //学习持黑 bool plays2=false; //学习持白 3、围棋电子棋盘的数据初始化。 //数据初始化 void wqinit(void) { BoardLines=19; //19X19路围棋盘 MoveCount=0; //一步棋未下,自然顺序 MoveCount1=0; //一步棋未下 ComputerPlaying=1; //默认电脑执黑先行 CurrentWho=0; //默认黑先; 黑方=0;白方=1;空方=2; CurrentX=0; //当前一步棋的X坐标,水平从左至右为1...19 CurrentY=0; //当前一步棋的Y坐标,垂直从上到下为1...19 timew=0,timeb=0; Playnum=0; //下棋顺序 Playnum1=0; //下面是棋盘初始化 for (int i=0;i<=BoardLines;i++) for (int j=0;j<=BoardLines;j++) { qipan[i][j].color=2; qipan[i][j].x=0; qipan[i][j].y=0; qipan[i][j].num=0; qipan[i][j].zt=0; } //清空棋谱记录,全部设为无效点。QiPu[0][x]留作它用 for (int i=0;i<500;i++) { qipu[i].color=2; qipu[i].x=0; qipu[i].y=0; qipu[i].num=0; qipu[i].zt=0; qipu[i].sm=0; qpsm1[i].n=0; qpsm1[i].t=0; strcpy(qpsm1[i].sm,"/"); } } 4、根据围棋规则编写的一些相关处理函数模块 围棋棋子的吃子,是根据围棋棋子的气数来计算的。气数为0的棋子应当从棋盘上拿掉。 围棋气数的计算问题,应当说是围棋软件的核心问题。 “气”是指棋子在棋盘上可以连接的交叉点,也是棋子的出路。 围棋的气数计算,要考虑一个围棋子的连通问题。 下面的图形中,交叉点的X代表棋子的气, [图1] 图1中右上角的黑子,有两个交叉点和它的直线相接,因此它有两口气。左上角的黑子 有三口气,而下边的黑子有四口气。 [图2] 图2中右边的黑子有四口气,中间连接在一起的两个黑子有六口气,而右边连接在一起的三个黑子有八口气。连接在一起的棋子越多,气也越多。 [图3] 图2中同样是四个连接在一起的黑子,左边的四个黑棋有十口气,中间的黑棋只有九口气,而右边的黑棋仅有八口气。 从上面分析,可以得出,计算一个棋子的气,还有分析该棋子周围的情况,因此我们利用递归函数来解决围棋气数的计算。实现看下面程序断。 int go[EDGE][EDGE]; /*表示棋盘 其中第0路和第20路为沉余数据 在 (X,Y)下黑子 go[x][y]=0;// 0表示黑 在 (X,Y)下白子 go[x][y]=1;// 1表示白子 在 (X,Y)提子 go[x][y]=2; //2表示空子 当前棋步脱先pass则 当前棋步 X坐标=0,y=0 否则 1<=x<=19, 1<=x<=19, */ int gokong[EDGE][EDGE]; //0=该空点未曾计算过气,1=已计算,避免重复计算公气 int gozi[EDGE][EDGE]; //0=该子未计算串气,1=已计算,避免重复计算同一个子的气 int goqi; //气数 //以上变量声明为全局变量 void str_qi(int x,int y,int hb) {//本函数计算 x,y 处的hb颜色棋子的气 gozi[x][y]=1; //标记本子已经计算过气 /////////////////////////////////////////////////////右临子 if (x+1<=19)//如果没有超出棋盘边线 { if ((go[x+1][y]==2)&&(gokong[x+1][y]==0)) //如果右临点为空并且该点未曾计算过气则 { goqi++; //气数加一 gokong[x+1][y]=1; //标记本空点已经计算过气 } else if ((go[x+1][y]==hb)&&(gozi[x+1][y]==0)) //否则如果右临点为和本子同色子并且该子未曾计算过气则 str_qi(x+1,y,hb); //递归调用到右临子 } /////////////////////////////////////////////////////左临子 if (x-1>=1) //果没有超出棋盘边线 { if ((go[x-1][y]==2)&&(gokong[x-1][y]==0)) //如果左临点为空并且该点未曾计算过气则 { goqi++; //气数加一 gokong[x-1][y]=1; //标记本空点已经计算过气 } else if ((go[x-1][y]==hb)&&(gozi[x-1][y]==0)) //否则如果左临点为和本子同色子并且该子未曾计算过气则 str_qi(x-1,y,hb); //递归调用到左临子 } ////////////////////////////////////////////////////下临子 if (y-1>=1)//如果没有超出棋盘边线 { if ((go[x][y-1]==2)&&(gokong[x][y-1]==0)) //如果下临点为空并且该点未曾计算过气则 { goqi++; //气数加一 gokong[x][y-1]=1; //标记本空点已经计算过气 } else if ((go[x][y-1]==hb)&&(gozi[x][y-1]==0)) //否则如果下临子点为和本子同色子并且该子未曾计算过气则 str_qi(x,y-1,hb); //递归调用到下临子 } ////////////////////////////////////////////////////上临点 if (y+1<=19)//如果没有超出棋盘边线 { if ((go[x][y+1]==2)&&(gokong[x][y+1]==0)) //如果上临点为空并且该点未曾计算过气则 { goqi++; //气数加一 gokong[x][y+1]=1; //标记本空点已经计算过气 } else if ((go[x][y+1]==hb)&&(gozi[x][y+1]==0)) //否则如果上临点为和本子同色子并且该子未曾计算过气则 str_qi(x,y+1,hb); //递归调用到上临子 } } int str_lib(int x,int y, int hb) { int i,j; for (i = 1; i <= 19; i++) for (j = 1; j <= 19; j++) { gozi[i][j] = 0; //初始化变量,表示该子未计算串气 gokong[i][j] = 0; //初始化变量,表示该空点未计算串气 } goqi=0; //串气初值 str_qi(x,y,hb); //调用串气子程序 return(goqi); //全局变量goqi带回串气值 } void shuanqi(void) { int i,j,cc,qq; for (i = 1; i <=19; i++) for (j = 1; j <= 19; j++) { go[i][j]=qipan[i][j].color; } for (i = 1; i <=19; i++) for (j = 1; j <=19; j++) { if (go[i][j]!=2) { cc=go[i][j]; qq=str_lib(i,j,cc); qipan[i][j].qs=qq; } } } 5、围棋的提子(吃子) 提子:就是把没有气的棋子从棋盘上拿掉。 下面函数实现提子功能。 void chizi(void) { int i,j,qq,cc; shuanqi(); for (i = 1; i <=19; i++) for (j = 1; j <= 19; j++) { qq=qipan[i][j].qs; cc=qipan[i][j].color; if (qq==0 && cc!=2 && cc!=CurrentWho) { qipan[i][j].color=2; qipan[i][j].x=i; qipan[i][j].y=j; qipan[i][j].num=0; qipan[i][j].zt=0; } } } 围棋程序设计的核心,基本完成,下面是输赢的判断问题。 6、围棋胜负判断 围棋盘上共有三百六十一个交叉点,一盘棋的胜负就是由对局双方所占据的交叉点的多少所决定的。更精确地说就是由双方活棋所占据的地域的大小来决定的。一个交叉点为一子,每方以一百八十又二分之一子为归本数,超过此数者为胜,不足此数者为负。 按我国现行的围棋规则规定,由于黑棋先走,有一定的先手威力,应由执黑的一方贴出2(3,4)子。所以黑所占的地域必须超过183(1,4)子(180 (1,2),2(3,4))才能取胜。比如黑棋数出来有185个子,即黑棋1(3,4)子。而白方的地域只要超过177(3,4)子(180(1,2),2(3,4))即可获胜。 [图4] 下面函数实现计算围棋的地域功能。在计算前,应当先去掉围棋中的死子。 // 计算围棋的地域 int sum[3]; //sum[0]=黑子数量,sum[1]=白子数量 int summ(void) { int i=0,j=0,c=2,k=2; sum[0]=0; sum[1]=0; sum[2]=0; for (i=1;i<=19;i++) { k=qipan[i][1].color; for (j=1;j<=19;j++) { c=qipan[j][i].color; switch (c) { case 2: if (k==2) sum[2]++; else sum[k]++; break; case 0: if (k==0) { sum[c]++; } else if(k==2) { sum[c]=sum[c]+sum[2]+1; k=c; sum[2]=0; } else if(k==1) { sum[c]++; k=c; sum[2]=0; } break; case 1: if (k==1) { sum[c]++; } else if(k==2) { sum[c]=sum[c]+sum[2]+1; k=c; sum[2]=0; } else if(k==0) { sum[c]++; k=c; sum[2]=0; } break; } } } return sum[0]; } 上面介绍了我国围棋规则,还有日本规则和应氏规则,这两种规则主要是计算胜负的不同,在围棋行棋上没有太大的区别。这方面,我们以后逐步是完成。 围棋程序的其他方面的设计和编写,主要依赖于计算机的编程环境。例如选择的计算机语言等等。后面我们针对C++Bulider 6的语言特点,专门介绍。
/
本文档为【电脑围棋程序编写思路】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索