当前位置:文档之家› C语言围棋对弈程序设计

C语言围棋对弈程序设计

C语言围棋对弈程序设计用C语言编写一个围棋对弈棋室的程序,模仿两人对弈的过程,其中包括自动提子功能,和自动点目功能。

1、围棋的一些基本常识:(1)围棋棋子的“气”见右图1所示黑棋1有4“气”,分别是水平方向上的左右各有一气,垂直方向上的上下各有一气,对角上的不是它的气。

图1棋子外“气”(2)提子(吃子),当下在棋盘上的棋子没有外气时便被提掉(死棋)。

图2、打吃状态图3、提子图2中黑1和白2都只有一口外气,图3黑先下7位白2没有外气被提掉。

图4、倒扑提子过程图5死穴图4演示了倒扑提子全过程,图中左上为原型,左下黑先黑41扑,右上白64提,右下黑93反提把白棋全吃掉。

(3)死穴:上图5黑1、3、5、7四颗黑子中间交差点对白棋来说是死穴,白棋下不进处,但对黑棋不影响可下见图下方。

2、自动提子功能实现下在棋盘上的棋子同类别的在某一方位上可能是一颗或是一片(纵横连续的),要实现自动提子首要的是计算清楚这些同类棋子的所有外气是多少,如果已经没有外气提掉。

一颗棋子下在棋盘上最多有4口外气(见图1),在边上有3气,在角上只有2气。

在程序中对于每一颗棋子检测外气描述如下:检测棋子可能有的方向上(上、下、左、右)是否有棋子,如果有,那么在该方向上没有外气。

如果在所有的方向上都有棋子,那么它在棋盘上是无外气的。

如果在它所有方向上没有同类棋子而且又无外气,那么该颗棋子可以提掉(见图3)。

如果在某一方向上有同类棋子,必须计算完连在一起同类的所有外气。

如果整片无外气,该片可以提掉(见图4)。

为了方便操作,在程序中对棋子定义了数据结构:t yp e def s tr uc t{in t r; //行号in t c; //列号in t s; //棋类别in t f; //棋子存活期in t q; //棋子外气数in t l; //棋子队列号in t n; //有无棋子}QZ;QZ Q iZ iB F[400];QZ BOX BF[19][19];检测棋盘上某一位置的外气实现函数:in t Ge t_Q I(int r,int c){in t t=0;if(r>0)if(BO XB F[r-1][c].n==0)t++;if(r<18)if(BO XB F[r+1][c].n==0)t++;if(c>0)if(BO XB F[r][c-1].n==0)t++;if(c<18)if(BO XB F[r][c+1].n==0)t++;r et ur n t;}为了更好的计算棋子的外气,把同类连在一起的棋子(纵横方向相连)编成一个列队,就是用一个统一的代号表示它们。

这是实现自动提子的关键所在,因为只要找到其中一颗棋子,根据代号就能找到全部。

在程序中用下函数描述: v o id Se le ct Lis ts(in t r,in t c) {in t i,j,k;if(r>0)if(BO XB F[r-1][c].n==1&&BOX BF[r-1][c].s==B OX BF[r][c].s) B OX BF[r][c].l=BOX BF[r-1][c].l;if(r<18){if(BO XB F[r+1][c].n==1&&BOX BF[r+1][c].s==BOX BF[r][c].s) {if(BO XB F[r][c].l<BOX BF[r+1][c].l){k=BOX BF[r+1][c].l;f or(i=0;i<19;i++)f or(j=0;j<19;j++)if(BO XB F[i][j].l==k)B OX BF[i][j].l=BO XBF[r][c].l;}e lse{k=BOX BF[r][c].l;f or(i=0;i<19;i++)f or(j=0;j<19;j++)if(BO XB F[i][j].l==k)B OX BF[i][j].l=BO XBF[r+1][c].l;}}}if(c>0){if(BO XB F[r][c-1].n==1&&BOX BF[r][c-1].s==B OX BF[r][c].s) {if(BO XB F[r][c].l<BO X BF[r][c-1].l){k=BOX BF[r][c-1].l;f or(i=0;i<19;i++)f or(j=0;j<19;j++)if(BO XB F[i][j].l==k)B OX BF[i][j].l=BO XBF[r][c].l;}e lse{k=BOX BF[r][c].l;f or(i=0;i<19;i++)f or(j=0;j<19;j++)if(BO XB F[i][j].l==k)B OX BF[i][j].l=BO XBF[r][c-1].l;}}}if(c<18){if(BO XB F[r][c+1].n==1&&BOX BF[r][c+1].s==BOX BF[r][c].s) {if(BO XB F[r][c].l<BOX BF[r][c+1].l){k=BOX BF[r][c+1].l;f or(i=0;i<19;i++)f or(j=0;j<19;j++)if(BO XB F[i][j].l==k)B OX BF[i][j].l=BO XBF[r][c].l;}e lse{k=BOX BF[r][c].l;f or(i=0;i<19;i++)f or(j=0;j<19;j++)B OX BF[i][j].l=BO XBF[r][c+1].l;}}}}检测每颗棋子外气的函数:v o id D et e ctQ i(){in t i,j;f or(i=0;i<19;i++)f or(j=0;j<19;j++)if(BO XB F[i][j].n==1)B OX BF[i][j].q=Get_Q I(i,j);}计算整个列队的外气函数:in t Ge t L is tsQ I(in t r,in t c,int t q) {in t i,j,k,mq=0;f or(i=0;i<19;i++)f or(j=0;j<19;j++){if(BO XB F[i][j].l==BOX BF[r][c].l&&B OXB F[i][j].s==t q)}r et ur n mq;}3、自动点目功能的实现当棋局收完官子,把所有可下的地方下完,把双方盘面上的死子清除后逐行扫描棋盘。

如果行开始无棋子,当遇到棋子时前面的空为该类棋子的实空。

如果行末无棋子,该行最大行号减空地数为何棋子实空为它所有。

各方实空加同类在棋盘上有效棋子数为各方总棋子数。

黑棋数减白棋数乘以2减贴目数为该局的最后结果。

v o id O ut Sc ore(){in t i,j,ws=0,bs=0,k;f loat s;c h ar c n[10];f or(i=0;i<19;i++){k=0;f or(j=0;j<19;j++){if(BO XB F[i][j].n==0)k++;if(BO XB F[i][j].n==1&&BOX BF[i][j].s==B L AC KQI){b s+=k+1;k=0;}if(BO XB F[i][j].n==1&&BOX BF[i][j].s==WH I TEQ I) {ws+=k+1;k=0;}if(j==18&&BOX B F[i][18].n==0){if(BO XB F[i][18-k].s==B LA CKQ I)b s+=k;if(BO XB F[i][18-k].s==W HI TEQI)ws+=k;}}}k=bs-ws;s=2*k-6.5;s etf ills ty le(1,9);B ar(470,250,615,310,4);s et co lor(4);if(s<0){s=-s;s pr in tf(cn,"%.1f",s);O ut Ch(mat[1],12,480,280,15);O ut Ch(mat[18],12,493,280,15);o u tt extx y(530,280,cn);O ut Ch(mat[5],12,570,280,15);}e lse{s pr in tf(cn,"%.1f",s);O ut Ch(mat[0],12,480,280,15);O ut Ch(mat[18],12,493,280,15);o u tt extx y(530,280,cn);O ut Ch(mat[5],12,570,280,15);}}4、棋子能下在棋盘上某一位置的条件首先当前准备下子的位置没有棋子存在。

其次是当前准备下子的位置如果有外气能下子,如果没有外气,那么分为两种情况。

一是当前准备下子位置在能有的方向上的棋子种类一样并且与准备下的棋子种类不一样,得该位置不能下子,如图5所示黑棋1、3、5、7中间的位置白棋不能下。

二是当前准备下子位置在能有的方向上棋子种类不一样,此时又分几种情况:一检测在能有方向上同类除了当前位置的外气外是否还有外气,如果有此处能下子,如果没有此处暂时不能下子,同时检测在能有的方向上不同类棋子除了当前位置外气外是否另有外气,如果有此处不能下子,如果无,那么此处能下子并且把没有外气的不同类棋子提掉(吃掉)。

实现函数:in t S e le c t(int r,int c,in t t q,int h q) {B OX BF[r][c].n=1;D et e ctQ i();if(r>0){if(BO XB F[r-1][c].s==t q){if(Get L is tsQ I(r-1,c,tq)>0){S h owC ir c le(r,c,t q);r et ur n 0;}}e lse{if(Get L is tsQ I(r-1,c,h q)==0){H id eC irc le(r-1,c,h q);S h owC ir c le(r,c,t q);r et ur n 0;}}}if(r<18){if(BO XB F[r+1][c].s==t q){if(Get L is tsQ I(r+1,c,t q)>0) {S h owC ir c le(r,c,t q);r et ur n 0;}}e lse{if(Get L is tsQ I(r+1,c,h q)==0) {S h owC ir c le(r,c,t q);r et ur n 0;}}}if(c>0){if(BO XB F[r][c-1].s==t q){if(Get L is tsQ I(r,c-1,tq)>0) {S h owC ir c le(r,c,t q);r et ur n 0;}}e lse{if(Get L is tsQ I(r,c-1,h q)==0) {H id eC irc le(r,c-1,h q);r et ur n 0;}}}if(c<18){if(BO XB F[r][c+1].s==t q){if(Get L is tsQ I(r,c+1,t q)>0) {S h owC ir c le(r,c,t q);r et ur n 0;}}e lse{if(Get L is tsQ I(r,c+1,h q)==0) {H id eC irc le(r,c+1,h q);S h owC ir c le(r,c,t q);r et ur n 0;}}}B OX BF[r][c].n=0;D et e ctQ i();r et ur n 0;}v o id Ma ke Q i(int r,in t c) { in t t q,h q,c o lo r;if(Rear<0)t q=BL AC KQI;e lse{if(Rear%2==0){h q=B LA CKQ I;t q=WH I TEQ I;}e lse{h q=W HI TEQ I;t q=BL AC KQI;}}if(BO XB F[r][c].n==0){if(Get_Q I(r,c))S h owC ir c le(r,c,t q);e lseS e le c t(r,c,t q,h q);}}以上两个函数很重要,在程序中是核心部分,对自动提子功能起到决定条件之一。

相关主题