通过C++语言来实现一个以windows控制台为展示平台的简单版五子棋程序,其中通过键盘输入来控制游戏中的行为(光标移动、落子、确认)。
规则要求某一方在横竖斜方向连续存在五个或五个以上本人所执棋子获得为获胜。当我们要扒一个已存在的程序时(有的是五子棋的程序,可以在互联网里找到很多)。
我们可以从他的UI入手,通过我们所观察到的,所感受到,所使用到的服务,来对软件进行分析,从而获得以上流程,但我们一旦需要将需求变为代码时,我们的设计就要考虑的更多了。
我们可以使用两个int类型的值来表示:白子- 1,黑子- 2,那么我们只要在棋盘中更改光标所在位置元素的值为1或2就可以了。
我们回顾一下光标移动的代码,我们会发现,中进行落子后,我们光标再次移动有可能会改变已记录的落子信息,为了使光标与棋子不冲突,我们使用两个图层,表示两个相同的棋盘。
本程序设计为人与人对弈,双方有一方五子连成一线即为赢。设计一游戏变量(3到9之间),用来控制显示面板的大小,即用户可选择生成3×3到9×9的棋盘。
五子棋C语言代码如下:#include <stdio.h>#include <bios.h>#include <ctype.h>#include <conio.h>#include <dos.h>#define CROSSRU 0xbf /*右上角点*/#define CROSSLU 0xda /*左上角点*/#define CROSSLD 0xc0 /*左下角点*/#define CROSSRD 0xd9 /*右下角点*/#define CROSSL 0xc3 /*左边*/#define CROSSR 0xb4 /*右边*/#define CROSSU 0xc2 /*上边*/#define CROSSD 0xc1 /*下边*/#define CROSS 0xc5 /*十字交叉点*//*定义棋盘左上角点在屏幕上的位置*/#define MAPXOFT 5#define MAPYOFT 2/*定义1号玩家的 *** 作键键码*/#define PLAY1UP 0x1157/*上移--'W'*/#define PLAY1DOWN 0x1f53/*下移--'S'*/#define PLAY1LEFT 0x1e41/*左移--'A'*/#define PLAY1RIGHT 0x2044/*右移--'D'*/#define PLAY1DO 0x3920/*落子--空格键*//*定义2号玩家的 *** 作键键码*/#define PLAY2UP 0x4800/*上移--方向键up*/#define PLAY2DOWN 0x5000/*下移--方向键down*/#define PLAY2LEFT 0x4b00/*左移--方向键left*/#define PLAY2RIGHT 0x4d00/*右移--方向键right*/#define PLAY2DO 0x1c0d/*落子--回车键Enter*//*若想在游戏中途退出, 可按 Esc 键*/#define ESCAPE 0x011b/*定义棋盘上交叉点的状态, 即该点有无棋子 *//*若有棋子, 还应能指出是哪个玩家的棋子 */#define CHESSNULL 0 /*没有棋子*/#define CHESS1 'O'/*一号玩家的棋子*/#define CHESS2 'X'/*二号玩家的棋子*//*定义按键类别*/#define KEYEX99v 0/*退出键*/#define KEYFALLCHESS 1/*落子键*/#define KEYMOVECURSOR 2/*光标移动键*/#define KEYINVALID 3/*无效键*//*定义符号常量: 真, 假 --- 真为1, 假为0 */#define TRUE 1#define FALSE 0/**********************************************************//* 定义数据结构 *//*棋盘交叉点坐标的数据结构*/struct point{int x,y}或者下面这个:#include <graphics.h>#include <stdlib.h>#include <stdio.h>#include <conio.h>#define N 15#define B 7#define STOP -10000#define OK 1#define NO 0#define UP 328#define DOWN 336#define LEFT 331#define RIGHT 333int a[N+1][N+1]int zx,zyint write=1,biaoji=0struct zn{long sumint yint x}w[N+1][N+1],max,max1void cbar(int i,int x,int y,int r)void map(int a[][])int getkey()int key()void zuobiao(int x,int y,int i)int tu(int a[][],int write)int wtu(int a[][],int write)int zhineng(int a[][])int zh5(int y,int x,int a[][])long zzh5(int b[][],int i)main(){int i,jint gdriver=DETECTint gmodeinitgraph(&gdriver,&gmode,"")zx=(N+1)/2zy=(N+1)/2for(i=1i<=Ni++)for(j=1j<=Nj++)a[i][j]=0map(a)i=1while(i){int k,nk=wtu(a,write)if(k==STOP) goto endmap(a)n=zhineng(a)if(n==STOP) goto endmap(a)}end:}int zhineng(int a[N+1][N+1]){int i,jint kmax.sum=-1for(i=0i<=Ni++)for(j=0j<+Nj++){w[i][j].sum=0w[i][j].x=iw[i][j].y=j}for(i=1i<=N-4i++)for(j=1j<=N-4j++){k=zh5(i,j,a)if(k==STOP) return (STOP)}for(i=1i<=Ni++)for(j=1j<=Nj++){if(max.sum<w[i][j].sum){max.sum=w[i][j].summax.y=imax.x=j}else if(max.sum==w[i][j].sum){if(((max.y-zy)*(max.y-zy)+(max.x-zx)*(max.x-zx))>((i-zy)*(i-zy)+(j-zx)*(j-zx)))max.sum=w[i][j].summax.y=imax.x=j}}if(a[max.y][max.x]==0){a[max.y][max.x]=-1zy=max.yzx=max.x}}int zh5(int y,int x,int a[N+1][N+1]){int i,jint b[6][6]long c[13]long d[6][6]long tempfor(i=yi<=y+4i++)for(j=xj<=x+4j++)b[i+1-y][j+1-x]=a[i][j]c[1]=b[1][1]+b[1][2]+b[1][3]+b[1][4]+b[1][5]c[2]=b[2][1]+b[2][2]+b[2][3]+b[2][4]+b[2][5]c[3]=b[3][1]+b[3][2]+b[3][3]+b[3][4]+b[3][5]c[4]=b[4][1]+b[4][2]+b[4][3]+b[4][4]+b[4][5]c[5]=b[5][1]+b[5][2]+b[5][3]+b[5][4]+b[5][5]c[6]=b[1][1]+b[2][1]+b[3][1]+b[4][1]+b[5][1]c[7]=b[1][2]+b[2][2]+b[3][2]+b[4][2]+b[5][2]c[8]=b[1][3]+b[2][3]+b[3][3]+b[4][3]+b[5][3]c[9]=b[1][4]+b[2][4]+b[3][4]+b[4][4]+b[5][4]c[10]=b[1][5]+b[2][5]+b[3][5]+b[4][5]+b[5][5]c[11]=b[1][1]+b[2][2]+b[3][3]+b[4][4]+b[5][5]c[12]=b[1][5]+b[2][4]+b[3][3]+b[4][2]+b[5][1]for(i=1i<=12i++){switch(c[i]){case 5:biaoji=1return(STOP)case -5:biaoji=-1return(STOP)case -4:c[i]=100000breakcase 4:c[i]=100000breakcase -3:c[i]=150breakcase 3:c[i]=150breakcase -2:c[i]=120breakcase 2:c[i]=100breakcase -1:c[i]=1breakcase 1:c[i]=1breakdefault: c[i]=0}}for(i=1i<=12i++){if(c[i]==150)c[i]+=zzh5(b,i)}for(i=1i<=5i++)for(j=1j<=5j++)d[i][j]=0for(i=1i<=5i++)for(j=1j<=5j++){if(i==j) d[i][j]+=c[11]if((i+j)==6) d[i][j]+=c[12]d[i][j]+=c[i]+c[j+5]}for(i=1i<=5i++)for(j=1j<=5j++){if(b[i][j]!=0)d[i][j]=-2}max1.sum=-1max1.y=0max1.x=0for(i=1i<=5i++)for(j=1j<=5j++){if(max1.sum<d[i][j]){max1.sum=d[i][j]max1.y=imax1.x=jw[i+y-1][j+x-1].sum+=max1.sum}else if(max1.sum==d[i][j]){if(((i+y-1-zy)*(i+y-1-zy)+(j+x-1-zx)*(j+x-1-zx))>((max1.y+y-1-zy)*(max1.y+y-1-zy)+(max1.x+x-1-zx)*(max1.x+x-1-zx))){max1.sum=d[i][j]max1.y=imax1.x=j}}}}long zzh5(int b[6][6],int n){int i,j,k,l,mswitch(n){case 1:i=b[1][1]j=b[1][2]k=b[1][3]l=b[1][4]m=b[1][5]breakcase 2:i=b[2][1]j=b[2][2]k=b[2][3]l=b[2][4]m=b[2][5]breakcase 3:i=b[3][1]j=b[3][2]k=b[3][3]l=b[3][4]m=b[3][5]breakcase 4:i=b[4][1]j=b[4][2]k=b[4][3]l=b[4][4]m=b[4][5]breakcase 5:i=b[5][1]j=b[5][2]k=b[5][3]l=b[5][4]m=b[5][5]breakcase 6:i=b[1][1]j=b[2][1]k=b[3][1]l=b[4][1]m=b[5][1]breakcase 7:i=b[1][2]j=b[2][2]k=b[3][2]l=b[4][2]m=b[5][2]breakcase 8:i=b[1][3]j=b[2][3]k=b[3][3]l=b[4][3]m=b[5][3]breakcase 9:i=b[1][4]j=b[2][4]k=b[3][4]l=b[4][4]m=b[5][4]breakcase 10:i=b[1][5]j=b[2][5]k=b[3][5]l=b[4][5]m=b[5][5]breakcase 11:i=b[1][1]j=b[2][2]k=b[3][3]l=b[4][4]m=b[5][5]breakcase 12:i=b[1][5]j=b[2][4]k=b[3][3]l=b[4][2]m=b[5][1]break}if((i==0&&j==1&&k==1&&l==1&&m==0))return (900)if((i==0&&j==-1&&k==-1&&l==-1&&m==0))return(1000)if((i==0&&j==0&&k==1&&l==1&&m==1)||(i==1&&j==1&&k==1&&l==0&&m==0))return(20)if((i==0&&j==0&&k==-1&&l==-1&&m==-1)||(i==-1&&j==-1&&k==-1&&l==0&&m==0))return(20)if((i==-1&&j==1&&k==1&&l==1&&m==1)||(i==1&&j==-1&&k==1&&l==1&&m==1)||(i==1&&j==1&&k==-1&&l==1&&m==1)||(i==1&&j==1&&k==1&&l==-1&&m==1)||(i==1&&j==1&&k==1&&l==1&&m==-1))return(-60)if((i==1&&j==-1&&k==-1&&l==-1&&m==-1)||(i==-1&&j==1&&k==-1&&l==-1&&m==-1)||(i==-1&&j==1&&k==-1&&l==-1&&m==-1)||(i==-1&&j==-1&&k==-1&&l==1&&m==-1)||(i==-1&&j==-1&&k==-1&&l==-1&&m==1))return(-60)}int wtu(int a[N+1][N+1],int write){int i=1map(a)zuobiao(zx,zy,1)while(i){int kk=tu(a,write)if(k==OK) i=0if(k==STOP) return (STOP)}}int getkey(){int key,lo,hikey=bioskey(0)lo=key&0x00ffhi=(key&0xff00)>>8return((lo==0) ? hi+256:lo)}int key(){int kk=getkey()switch(k){case 27: return (STOP)case 13:case ' ': return (OK)case 328: return (UP)case 336: return (DOWN)case 331: return (LEFT)case 333: return (RIGHT)default: return (NO)}}void zuobiao(int x,int y,int i){int rif(i!=0){setcolor(GREEN)for(r=1r<=5r++)circle(75+25*x,25+25*y,r)}else{if(a[zy][zx]==1){setcolor(8)for(r=1r<=5r++)circle(75+25*x,25+25*y,r)}else if(a[zy][zx]==-1){setcolor(WHITE)for(r=1r<=5r++)circle(75+25*x,25+25*y,r)}else{setcolor(B)for(r=1r<=5r++)circle(75+25*x,25+25*y,r)setcolor(RED)line(75+25*zx-5,25+25*zy,75+25*x+5,25+25*zy)line(75+25*zx,25+25*zy-5,75+25*zx,25+25*zy+5)}}}int tu(int a[N+1][N+1],int write){int kre:k=key()if(k==OK){if(a[zy][zx]==0){a[zy][zx]=write}elsegoto re}if(k==STOP) return(STOP)if(k==NO) goto reif(k==UP){int i,jif(zy==1) j=zyelse j=zy-1zuobiao(zx,zy,0)zuobiao(zx,j,1)zy=jgoto re}if(k==DOWN){int i,jif(zy==N) j=zyelse j=zy+1zuobiao(zx,zy,0)zuobiao(zx,j,1)zy=jgoto re}if(k==LEFT){int i,jif(zx==1) i=zxelse i=zx-1zuobiao(zx,zy,0)zuobiao(i,zy,1)zx=igoto re}if(k==RIGHT){int i,jif(zx==N) i=zxelse i=zx+1zuobiao(zx,zy,0)zuobiao(i,zy,1)zx=igoto re}}void cbar(int i,int x,int y,int r){if(i!=0){if(i==1)setcolor(8)else if(i==-1)setcolor(WHITE)for(i=1i<=ri++){circle(x,y,i)}}}void map(int a[N+1][N+1]){int i,jcleardevice()setbkcolor(B)setcolor(RED)for(i=0i<Ni++){line(100,50+25*i,75+N*25,50+25*i)line(100+25*i,50,100+25*i,25+N*25)}for(i=1i<=Ni++)for(j=1j<=Nj++)cbar(a[i][j],75+25*j,25+25*i,10)}
我浏览了一下你的代码,你对胜利的判断采用的是检查整个棋盘的方式,这样做的最大弊端自然是低效,而且在编写斜方向判断的时候比较复杂。我建议你采用下子后判断的方式,即玩家1下了一个字后,像该子周围8个方向检查是否存在5子的情况,只需要一个判断方法,而且较为简单。void chooseONE()
{
printf("第一玩家请选择下棋位置\n")
printf("第几个直的\n")
scanf("%d",&co)
printf("第几个横的\n")
scanf("%d",&ro)
while(arr[ro][co]==1||arr[ro][co]==2)
{
printf("重复了!!!\n")
printf("第几个直的\n")
scanf("%d",&co)
printf("第几个横的\n")
scanf("%d",&ro)
}
arr[ro][co]=1
//这里加判断代码,建议用一个判断函数,我给你写个吧
}
//我这里这个方法写了个大概,你看一下和你的代码结合一下就可以了,我用i和j作为for循环的变量,你用来做最大的长宽值,这些你都要改一下。
flag作为判断是否胜利的标志,playerNum是玩家的标志,分1和2,这个函数只写了左和左上的判断,其他方向楼主仿照着写
int win(int row, int col, int playerNum){
int i = 0,j = 0
int flag = 1
if(row - 4 >= 0){
flag = 1
for(i = rowi >= 0i--){
if(arr[i][j] != playerNum){
flag = 0
break
}
}
if(flag == 1){
return 1
}
}
if(row - 4 >= 0 &&col - 4 >= 0){
flag = 1
for(i = row ,j = col i >= 0&&j>=0i--,j--){
if(arr[i][j] != playerNum){
flag = 0
break
}
}
if(flag == 1){
return 1
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)