版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、五子棋程序1. 项目简介该程序为简易的五子棋程序,可以实现人人对战和人机对战,并且有自动报警功能,即当对方已有一个三连的构型时可以提醒你,拥有判断输赢的功能,当一种颜色的棋的五个子连成一条线时,可判断谁输谁赢。拥有复盘和和悔棋的功能,其中对于复盘功能,每次你可以选择显示下一步或上一步的棋盘,对于悔棋,每次后退两步,即回到上一轮你要开始下棋的时候。2. 设计思想程序的主体是根据玩家选择的对战模式,设计一个让双方循环下棋的程序。根据题目要求,每次下棋时都会出现一个让玩家选择功能的菜单,菜单包括下棋、复盘、悔棋、退出等功能。这时就要编写一个程序,让这个程序根据玩家的不同选择做出不同的处理,以满足玩家
2、的要求。最后便是各种功能相应函数的编写。以上便是该程序的整体设计思想。3. 功能及其实现(含源程序)对于该五子棋程序的基本功能,大的方面有如人机对战和人人对战的功能,小的方面有下棋、复盘、悔棋、警报、判断输赢和退出等功能,并且增加了许多人性化设计,如警报时会有报警提示音,而且字体会变红的变化。而其中最重要的几个程序便是人机对战程序中电脑算法的编写、判断输赢以及报警程序的编写、复盘和悔棋程序的编写。对于画棋盘程序,我是这样编写的:定义一个整型二维数组,执白棋者每下一子,便根据该坐标给相应的二维数组赋值为1,执黑棋者每下一子,便根据该坐标给相应的二维数组赋值为2,未落子的地方,则赋值为0。此时再定
3、义一个字符串二维数组,扫描前面的整型二维数组,如果值为1,则将对应的字符串数组表示为白棋,如果值为2,则将对应的字符串数组表示为黑棋,如果值为0,则将对应的字符串数组表示为方框,最后输出这个字符串数组,便画好了一张棋盘。对于人机对战算法,我是这样思考的:该过程无非是让电脑根据当前棋盘的落子,在棋盘上选择一个“最合适”的位置下棋,而“最合适”在程序中实现便是计算当前棋盘中价值最大的点。那如何计算价值最大的点呢?这就要根据棋盘中不同颜色的棋子所构成的棋型来判断。举个例子,如果棋盘中已有一个对方连成三连的构型时,则这三个子的两头的且靠近己方的位置便为价值最大的点,则电脑落子时落在这里,其次便是己方这
4、种构型的两端。以此类推便为我的人机对战算法。对于判断输赢的功能,我是这样实现的:玩家 每下一次棋,便把该子的坐标传给判断输赢的函数。然后从该子开始,先向右判断是否包括该子有五个颜色一样的子,然后又从该子开始向左判断,然后向右下判断,然后向左上判断,然后向下判断,然后向上判断,然后向左下判断,最后向右上判断。如果有一个方向满足情况,便返回1,如果都不满足,便返回0,然后根据返回值判断输赢。对于报警功能,则仿照上述判断输赢的程序,如果有三个子连在一起,则返回1,否则返回0。根据返回值判断是否报警。对于复盘功能,我是这样实现的:定义一个结构体,里面存放前面画棋盘时提到的字符串数组,每下一步,便将该结
5、构体包含的数据写入文件中,复盘时,根据玩家要求,从文件中读取数据,然后输出上一步或下一步棋盘。对于悔棋功能,我是这样实现的:我定义了一个全局变量,然后定义了一个指向该全局变量的指针,每下一次棋,该指针则加1,当玩家要悔棋时,则该指针减2,将前面两步对应的整型二维数组的值赋为0,然后输出该全局变量对应的结构体中的字符串,即可实现悔棋的功能。以上便是我编写的五子棋程序所包含的功能及其实现方法。下面是部分重要的源程序:typedef struct jilu/*定义结构体保存所有棋局,用于复盘和悔棋*/ char pN+1N+1MAXLEN;JILU;int main() JILU jilu256;
6、int statusNN=K; int op1=0,op2=0,op3=0,op4=0,a,b;/*op1,op2记录执白棋落子坐标,op3,op4记录执黑棋落子坐标*/ int total=0;/*记录总步数*/ int *d = &total;/*定义指针,用于改变total的值*/ setcolor(14); printf("*欢迎你进入挑战与乐趣并存的五子棋游戏!*n"); printf(" Programed by 夏阳升n");b:printf(" 请选择对战模式:(1、双人对战 2、人机对战):"); scanf
7、("%d",&a); if (a=1) setcolor(11); printf("欢迎使用双人对战模式!n"); printf("友情提示:本游戏有警报功能(如对方已经有一个三连的构型了,则可提醒玩家).n"); setcolor(10); Draw(status,jilu,total); do setcolor(14); l:printf("现在是执白棋者下,请选择功能(1:下棋;2:悔棋;3:复盘;4;退出):"); scanf("%d",&b); switch(b) ca
8、se 1: printf("请输入你要落子的位置:"); scanf("%d %d",&op1,&op2); if (statusop1op2) setcolor(12); printf("该位置已有棋子,请另输入坐标:"); scanf("%d %d",&op1,&op2); if (op1<0|op1>15|op2<0|op2>15) setcolor(12); printf("坐标错误!请从新输入:"); scanf("%d
9、 %d",&op1,&op2); statusop1op2=M; *d = *d+1; system("cls"); setcolor(10); Draw(status,jilu,total); if (PD(status,op1,op2) setcolor(12);/*如有危险,则界面变为红色,且有提示音*/ printf("执黑棋者有危险!an"); if (Judge(status,op1,op2) setcolor(12); printf("执白棋者获胜!n"); break; case 2: sys
10、tem("cls"); *d = *d - 2; if (total>=0) setcolor(10); Huiqi(status,jilu,op1,op2,op3,op4,total); else printf("已经悔到底了,不能再悔了n"); goto l; break; case 3:system("cls"); Fupan(jilu,total); break; case 4:exit(0); default:setcolor(12); printf("输入错误!"); goto l; m:prin
11、tf("现在是执黑棋者下,请选择功能(1:下棋;2:悔棋;3:复盘;4;退出):"); while(total<=255); printf("这局为平局"); exit(0); if (a=2) setcolor(11); printf("欢迎使用人机对战模式!n"); printf("友情提示:本游戏有警报功能(如果电脑已经有一个三连的构型了,则可提醒玩家).n"); setcolor(10); Draw(status,jilu,total); do setcolor(14); y:printf("
12、;请你选择功能(1:下棋;2:悔棋;3:复盘;4;退出):"); system("cls"); setcolor(10); Draw(status,jilu,total); if (Judge(status,op1,op2) setcolor(12); printf("恭喜你,把电脑打败了!n"); goto y; break; case 2:system("cls"); *d = *d-2; if (total>=0) setcolor(10); Huiqi(status,jilu,op1,op2,op3,op4,t
13、otal); else printf("已经悔到底了,不能再悔了n"); goto y; break; case 3:system("cls"); Fupan(jilu,total); goto y; break; case 4:exit(0); default:setcolor(12); printf("输入错误!"); goto y;DX(status,&op3,&op4); statusop3op4=R; *d=*d+1; system("cls"); setcolor(10); Draw(s
14、tatus,jilu,total); setcolor(14); printf("电脑下在%d %d处.",op3,op4);while(total<=255); printf("这局为平局"); exit(0); /*函数功能:画棋盘*/void Draw(int statusN,JILU jilu,int total) int i,j; for(i=0;i<N;i+) for(j=0;j<N;j+) if(statusij=M) strcpy(jilutotal.pi+1j,"0"); if(statusij=R
15、) strcpy(jilutotal.pi+1j,"0"); if(statusij=K) strcpy(jilutotal.pi+1j,"0"); strcpy(jilutotal.p1N,"00");strcpy(jilutotal.p2N,"10");strcpy(jilutotal.p3N,"20");strcpy(jilutotal.p4N,"30");strcpy(jilutotal.p5N,"40");strcpy(jilutotal.p6N
16、,"50");strcpy(jilutotal.p7N,"60");strcpy(jilutotal.p8N,"70");strcpy(jilutotal.p9N,"80");strcpy(jilutotal.p10N,"90");strcpy(jilutotal.p11N,"100");strcpy(jilutotal.p12N,"110");strcpy(jilutotal.p13N,"120");strcpy(jilutotal.
17、p14N,"130");strcpy(jilutotal.p15N,"140");strcpy(jilutotal.p16N,"150"); strcpy(jilutotal.p00,"00");strcpy(jilutotal.p01,"1 0");strcpy(jilutotal.p02,"20");strcpy(jilutotal.p03,"3 0");strcpy(jilutotal.p04,"40");strcpy(jilut
18、otal.p05,"5 0");strcpy(jilutotal.p06,"60");strcpy(jilutotal.p07,"7 0");strcpy(jilutotal.p08,"80");strcpy(jilutotal.p09,"9 0");strcpy(jilutotal.p010,"100");strcpy(jilutotal.p011,"110");strcpy(jilutotal.p012,"120");strcpy(
19、jilutotal.p013,"130");strcpy(jilutotal.p014,"140");strcpy(jilutotal.p015,"150");strcpy(jilutotal.p016," 0"); for (i=0;i<=N;i+) for (j=0;j<=N;j+) printf("%s",jilutotal.pij); printf("n"); FILE *fp; if (fp=fopen("game.txt",&quo
20、t;w")=NULL)/*以写方式打开文本文件*/ printf("文件game.txt打开失败!n"); exit(0); fwrite(jilu,sizeof(JILU),total,fp);/*按数据块写文件*/ fclose(fp);/*函数功能:预报危险*/int PD(int statusN,int p,int q) int k,m,P,Q; int n=1; P=p; Q=q; k=statuspq; while(n!=5) m=0; while(k=statuspq) m+; if(m=3)/*如果有三个子连在一起,则返回1*/ return 1;
21、 Zuanxiang(n,&p,&q);/*由n的值决定往哪个方向判断*/ if(p<0|p>15|q<0|q>15) break; n+=4; m-=1; p=P; q=Q;/*每判断完一个方向之后改变n的值,转动方向由n的不同值决定*/ while(k=statuspq) m+; if(m=3) return 1; Zuanxiang(n,&p,&q); if(p<0|p>15|q<0|q>15) break; n-=3; p=P; q=Q; /* 不成功则判断下一组方向 */ return 0;int Jud
22、ge(int statusN,int p,int q) int k,m,P,Q; int n=1; P=p; Q=q; k=statuspq; while(n!=5) m=0; while(k=statuspq) m+; if(m=5)/*如果连成五子,则返回1*/ return 1; Zuanxiang(n,&p,&q);/*由n的值决定往哪个方向判断*/ if(p<0|p>15|q<0|q>15) break; n+=4; m-=1; p=P; q=Q;/*每判断完一个方向之后改变n的值,转动方向由n的不同值决定*/ while(k=statuspq
23、) m+; if(m=5) return 1; Zuanxiang(n,&p,&q); if(p<0|p>15|q<0|q>15) break; n-=3; p=P; q=Q; /* 不成功则判断下一组方向 */ return 0;void Huiqi(int statusN,JILU jilu,int op1,int op2,int op3,int op4,int total) int i,j,x; statusop1op2=K; statusop3op4=K; for (i=0;i<=N;i+) for (j=0;j<=N;j+) pri
24、ntf("%s",jilutotal.pij); printf("n"); void Fupan(JILU jilu,int total) int i,j,k=1; int c; FILE *fp; if (fp=fopen("game.txt","r")=NULL)/*以写方式打开文本文件*/ printf("文件game.txt打开失败!n"); exit(0); for (i=0;!feof(fp);i+) fread(&jilui,sizeof(JILU),total,fp);
25、fclose(fp); setcolor(10); printf("第一步棋局如下:n"); for (i=0;i<=N;i+) for (j=0;j<=N;j+) printf("%s",jiluk.pij); printf("n"); do printf("请选择(1:显示上一步棋局 2:显示下一步棋局):"); scanf("%d",&c); if (c=1) system("cls"); k=k-1; printf("第%d步棋局如下:n
26、",k); for (i=0;i<=N;i+) for (j=0;j<=N;j+) printf("%s",jiluk.pij); printf("n"); if (c=2) system("cls"); k=k+1; printf("第%d步棋局如下:n",k); for (i=0;i<=N;i+) for (j=0;j<=N;j+) printf("%s",jiluk.pij); printf("n"); while (k>=0&a
27、mp;&k<=total);void Zuanxiang(int n,int *i,int *j) switch(n) case 1: *j+=1; break; case 2: *i+=1; *j+=1; break; case 3: *i+=1; break; case 4: *j-=1; *i+=1; break; case 5: *j-=1; break; case 6: *i-=1; *j-=1; break; case 7: *i-=1; break; case 8: *j+=1; *i-=1;break; void DX(int statusN,int *p,int
28、 *q) /* 电脑下子 *p *q返回下子坐标 */ int i,j,k,max=0,I,J; /* I J为下点坐标 */ for(i=0;i<16;i+) for(j=0;j<16;j+) if(statusij=K) /* 历遍棋盘,遇到空点则计算价值,取最大价值点下子。 */ k=Suanzhi(status,i,j); if(k>=max) I=i; J=j; max=k; *p=I; *q=J;int Suanzhi(int statusN,int p,int q) /* 计算空点p q的价值 以k返回 */ int n=1,k=0,k1,k2,K1,K2,X1
29、,Y1,Z1,X2,Y2,Z2,temp; int a244=40,400,3000,10000,6,10,600,10000,20,120,200,0,6,10,500,0,30,300,2500,5000,2,8,300,8000,26,160,0,0,4,20,300,0; /* 数组a中储存己方和对方共32种棋型的值 己方0 对方1; 活0 冲1 空活2 空冲3 ;子数0-3(0表示1个子,3表示4个子)*/ while(n!=5) k1=Qiju(status,n,p,q); n+=4; /* k1,k2为2个反方向的棋型编号 */ k2=Qiju(status,n,p,q); n-
30、=3; if(k1>k2) temp=k1; k1=k2; k2=temp; /* 使编号小的为k1,大的为k2 */K1=k1; K2=k2; /* K1 K2储存k1 k2的编号 */ Z1=k1%10; Z2=k2%10; k1/=10; k2/=10; Y1=k1%10; Y2=k2%10; k1/=10; k2/=10; X1=k1%10; X2=k2%10; /* X Y Z分别表示 己方0对方1 活0冲1空活2空冲3 子数0-3(0表示1个子,3表示4个子) */ if(K1=-1) if(K2<0) k+=0; continue; else k+=aX2Y2Z2+5
31、; continue; ; /* 空棋型and其他 */ if(K1=-2) if(K2<0) k+=0; continue; else k+=aX2Y2Z2/2; continue; ; /* 边界冲棋型and其他 */ if(K1=-3) if(K2<0) k+=0; continue; else k+=aX2Y2Z2/3; continue; ; /* 边界空冲棋型and其他 */ if(K1>-1&&K1<4)&&(K2>-1&&K2<4)|(K2>9&&K2<18)|(K1
32、>99&&K1<104)&&( K2>99&&K2<104)|(K2>109&&K2<115) /* 己活己活 己活己冲 对活对活 对活对冲 的棋型赋值*/ if(Z1+Z2>=2) k+=aX2Y23; continue; else k+=aX2Y2Z1+Z2+1; continue; if(K1>9&&K1<18)&&(K2>9&&K2<18)|(K1>109&&K1<118)&
33、&(K2>109&&K2<118) /* 己冲己冲 对冲对冲 的棋型赋值*/ if(Z1+Z2>=2) k+=10000; continue; else k+=0; continue; if(K1>-1&&K1<4)&&(K2>99&&K2<104)|(K2>109&&K2<118)|(K1>9&&K1<18)&&(K2>99&&K2<104)|(K2>109&&
34、;K2<118) /* 己活对活 己活对冲 己冲对活 己冲对冲 的棋型赋值*/ if(Z1=3|Z2=3) k+=10000; continue; else k+=aX2Y2Z2+aX1Y1Z1/4; continue; else k+=aX1Y1Z1+aX2Y2Z2; continue; /* 其他棋型的赋值 */ return k;int Qiju(int statusN,int n,int p,int q) /* 返回空点p q在n方向上的棋型号 n为1-8方向 从右顺时针开始数 */ int k,m=0; /* 棋型号注解: 己活000-003 己冲010-013 对活100-1
35、03 对冲110-113 己空活020-023 己空冲030-033 对空活120-123 对空冲130-133 空-1 边界冲-2 边界空冲-3*/ Zuanxiang(n,&p,&q); if(p<0|p>15|q<0|q>15) k=-2; /* 边界冲棋型*/ switch(statuspq) case R: m+; Zuanxiang(n,&p,&q); if(p<0|p>15|q<0|q>15) k=m+9; return k; while(statuspq=R) m+; Zuanxiang(n,&p,&q); if(p<0|p>15|q<0|q>15) k=m+9; return k; if(statuspq=K) k=m-1; /* 己方活棋型 */ else k=m+9; /* 己方冲棋型 */ break; case M: m+; Zuanxiang(n,&p,&q); if(p<0|p>15|q<0|q>15) k=m+109; return k; while(statuspq=M) m+; Zuanxiang(n,&p,&q);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 上海求婚活动策划方案(3篇)
- 古筝独奏活动策划方案(3篇)
- 女裤清仓活动方案策划(3篇)
- 年度大会活动策划方案(3篇)
- 新奇宣传活动策划方案(3篇)
- 汽车晚宴活动方案策划(3篇)
- 理疗-促销活动策划方案(3篇)
- 饭局话题活动方案策划(3篇)
- 妊娠合并血栓性疾病国际预防策略本土化
- 商业势能营销方案(3篇)
- 电力电子技术培训
- 2026国家基本公卫预防接种考试题库及答案
- 冲床吊装施工方案(3篇)
- 2025初二微机考试试题及答案
- TCEC5023-2020电力建设工程起重施工技术规范报批稿1
- 低血糖的诊断及鉴别诊断
- 卫生部病历书写基本规范2025年版
- 化学学科介绍
- 2026年洛阳商业职业学院单招职业技能考试必刷测试卷带答案
- 计算机网络专升本考试题(附答案)
- 农民工工资代发协议范本及说明
评论
0/150
提交评论