收藏 分销(赏)

c语言报告五子棋.doc

上传人:Fis****915 文档编号:551515 上传时间:2023-12-06 格式:DOC 页数:16 大小:289KB 下载积分:6 金币
下载 相关 举报
c语言报告五子棋.doc_第1页
第1页 / 共16页
c语言报告五子棋.doc_第2页
第2页 / 共16页


点击查看更多>>
资源描述
C语言课程设计报告 题目: 简单的c五子棋 设计者: 方阳 专业班级: 软件工程1303班 学号: 311309060324 指导老师: 刘洁 所属系部: 计算机学院 2014年6月25日 河南理工大学1、设计任务书 1.1、 题目与要求: 本人计划编写一个简单的c五子棋,应用C语言编写程序可以在计算机上实现二人对弈五子棋功能。二人对弈五子棋程序由图像生成、光标移动与落子、判断胜负和系统帮助等子程序构成;程序中应用了结构体、数组、全局变量、按键处理和图形编程等元素和语句。程序通过棋盘和棋子图像生成、二人移子与落子和判断胜负等功能的实现,在计算机上实现了二人五子棋对弈。 1.2、 本系统涉及的知识点: 结构、数组、循环、函数、分支、 2、功能设计 根据功能需求,将程序分为图形显示、玩家控制、胜负判断和玩家计分四个模块,以下分析各模块的需求。 图形显示模块:程序开始运行时,给出欢迎及帮助界面;游戏开始后要求生成19×19的棋盘图像,并在棋盘上方提示当前落子方棋子颜色,游戏进行过程中,要求实时显示棋盘上已落下的棋子;分出胜负后,要求给出游戏结束画面。 玩家控制模块:程序开始时,需玩家确定而后开始游戏;游戏过程中,两个玩家通过不同的按键移动光标,选择落子;游戏结束时,有玩家选择是否开始新棋局。 胜负判断模块:实时监测棋盘上棋子,一旦某一色棋子出现五子连线,终止游戏程序,并着色连成一线的五子,弹出该色玩家胜出界面。 玩家计分模块:一方玩家再胜利后通过对文件的操作进行计分,并输出于计分板上。 2.1、算法设计 根据程序需求分析结果,可以得出程序的总体结构图如图。 2.2部分模块流程图 程序流程图 3、程序代码设计 3.1 图形模块 ①initgr() /* BGI初始化 */ { int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */ registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */ initgraph(&gd, &gm, ""); } ② welcome() /*欢迎界面*/ { initgr() ; /*初始化*/ clearviewport(); /*清屏*/ setcolor(2); /*设置颜色*/ settextstyle(0,0,6); /*样式*/ outtextxy(180,180,"Welcome");/*位置以及内容*/ settextstyle(0,0,2); /*文本样式*/ outtextxy(240,420,"press any key to continue");/*位置以及内容*/ getch(); /*press any key to continue*/ } ③ help() /*帮助界面,基本操作同welcome();函数*/ { initgr(); clearviewport(); setcolor(2); settextstyle(0,0,2); outtextxy(60,100,"P1 move; W S A D "); outtextxy(60,120," set : space "); outtextxy(60,180,"P2 move: up down left right "); outtextxy(60,200," set: Enter"); outtextxy(60,240,"You can press Backspace to pull back!") ; outtextxy(60,280,"When you want to quit the game,"); outtextxy(60,300,"press Esc."); outtextxy(220,440,"press any key to continue"); getch(); } ④ bye() /*say bye~@!,实现功能同上*/ { initgr(); clearviewport(); setcolor(4) ; settextstyle(0,0,6); outtextxy(130,180,"Thank you!"); settextstyle(0,0,2); outtextxy(240,420,"press any key to quit"); getch(); } ⑤ board()/*画棋盘*/ { setcolor(14); /*线色*/ setfillstyle(1,6); /*样式*/ bar(120,50,520,450); /*棋盘底*/ for(k=0;k<21 ;k++) { line(120+20*k,50,120+20*k,450) ; /*竖线*/ line(120,50+20*k,520,50+20*k) ; /*横线*/ } setfillstyle(1,9) ; bar(540,200,620,300); /*1p2p两边框*/ bar(20,200,100,300); setcolor(2); settextstyle(3,0,4); outtextxy(50,210,"1p"); outtextxy(570,210,"2p"); delay(50000); show(); /*显示动态变色效果的标题*/ moveto(320,250); /*初始化中心位置*/ border(); /*画定位框*/ p1turn(); /*p1开始落子,游戏开始*/ } ⑥white() /*画白棋*/ { setcolor(15); setfillstyle(1,15); circle(getx(),gety(),9); floodfill(getx(),gety(),15); } black() /*画黑棋*/ { setcolor(0); setfillstyle(1,0); circle(getx(),gety(),9); floodfill(getx(),gety(),0); } green() /*用粉色着色连珠时的棋子*/ { setcolor(13); setfillstyle(1,13); circle(getx(),gety(),9); floodfill(getx(),gety(),13); } ⑦ p1turn()/*画左边边框内白棋子*/ { setcolor(15); setfillstyle(1,15); circle(60,250,9); floodfill(60,250,15); settextstyle(3,0,4); outtextxy(20,280,"white turn"); } p2turn() /*右边边框内黑色棋子*/ { setcolor(0); setfillstyle(1,0); circle(580,250,9); floodfill(580,250,0); settextstyle(3,0,4); outtextxy(540,280,"black turn"); } p1del()/*不是1turn时候抹去左边边框内棋子*/ { setfillstyle(1,9) ; floodfill(60,250,9); setcolor(9); settextstyle(3,0,4); outtextxy(20,280,"white turn"); } p2del()/*不是2turn时候抹去右边边框内棋子*/ { setfillstyle(1,9); floodfill(580,250,9) ; setcolor(9); settextstyle(3,0,4); outtextxy(540,280,"black turn"); } ⑧ border() /*画定位框*/ { setcolor(14); line(getx()-8,gety()-9,getx()-3,gety()-9); /*通过画线函数画出定位框*/ line(getx()+8,gety()-9,getx()+3,gety()-9); line(getx()-8,gety()-9,getx()-8,gety()-4); line(getx()+8,gety()-9,getx()+8,gety()-4); line(getx()-8,gety()+9,getx()-3,gety()+9); line(getx()+8,gety()+9,getx()+3,gety()+9); line(getx()-8,gety()+9,getx()-8,gety()+4); line(getx()+8,gety()+9,getx()+8,gety()+4); } delborder() /*除去定位框*/ { setcolor(6); /*本质在于颜色覆盖*/ line(getx()-8,gety()-9,getx()-3,gety()-9); line(getx()+8,gety()-9,getx()+3,gety()-9); line(getx()-8,gety()-9,getx()-8,gety()-4); line(getx()+8,gety()-9,getx()+8,gety()-4); line(getx()-8,gety()+9,getx()-3,gety()+9); line(getx()+8,gety()+9,getx()+3,gety()+9); line(getx()-8,gety()+9,getx()-8,gety()+4); line(getx()+8,gety()+9,getx()+8,gety()+4); } ⑨ drawmat(char *mat,int matsize,int x,int y,int color)/*点阵图所用标准输出方式*/ { int i,j,k,m; m=(matsize-1)/8+1; for(j=0;j<matsize;j++) for(i=0;i<m;i++) for(k=0;k<8;k++) if(mat[j*m+i]&(0x80>>k)) putpixel(x+i*8+k,y+j,color); } show() /*动态点阵图中文闪烁效果*/ { for(n=0;n<3;n++) { delay(10000); drawmat(wu32K,32,240,0,3);/*输出点阵图的“五”字*/ delay(10000); drawmat(zi32K,32,290,0,3); delay(10000); drawmat(qi32K,32,340,0,3); delay(10000); drawmat(wu32K,32,240,0,2); delay(10000); drawmat(zi32K,32,290,0,2); delay(10000); drawmat(qi32K,32,340,0,2); } 3.2 玩家操作模块 ① p1move() /*玩家1操作*/ { switch(bioskey(0)) /*bioskey函数对键盘操作*/ { case W: /*上移*/ 所有if语句作用在于如果落子即将溢出边框,让其改变位置到另一端,例如移动棋盘最上端,若继续向上移动,则移动至棋盘最下端对应位置 {if(gety()<90) {delborder();moveto(getx(),430);} delborder();moverel(0,-20);border();p1move();} case A: /*左移*/ { if(getx()<160) {delborder();moveto(500,gety());} delborder();moverel(-20,0);border();p1move();} case S: /*下移*/ {if(gety()>410) {delborder();moveto(getx(),70);} delborder();moverel(0,20);border();p1move();} case D: /*右移*/ { if(getx()>480) {delborder();moveto(140,gety());} delborder();moverel(20,0);border();p1move();} case SP: /*落子*/ {if(a[getx()][gety()]!=6) /*判定如果棋盘此处无子才能下,否则重新调用p1move函数*/ {p1move();} delborder(); /*去除定位框*/ white(); /*画棋子*/ a[getx()][gety()]=1;/*将所在位置对应的数组点赋值为1*/ win(); /*判断胜负*/ border(); /*在新的位置画出定位框*/ 对左右两边提示框操作,提示轮到2p进行操作,并调用p2move()函数 p1del(); p2turn(); p2move();} case ESC: / *结束游戏*/ {bye();closegraph(); exit(0);} case BACK : /*悔棋操作*/ {back();p1del();p2turn();p2move();} default: p1move(); } } ② p2move() /*玩家2操作*/ P2move(); 函数与p1move();函数基本作用相同 { switch(bioskey(0)) { case UP: {if(gety()<90) {delborder();moveto(getx(),430);} delborder();moverel(0,-20);border();p2move();} case LEFT: {if(getx()<160) {delborder();moveto(500,gety());}delborder();moverel(-20,0);border();p2move();} case DOWN: {if(gety()>410) {delborder();moveto(getx(),70);}delborder();moverel(0,20);border();p2move();} case RIGHT: { if(getx()>480) {delborder();moveto(140,gety());}delborder();moverel(20,0);border();p2move();} case ENTER: {if(a[getx()][gety()]!=6) {p2move();}delborder();black();a[getx()][gety()]=0;win();border();p2del();p1turn();p1move();} default: p2move(); case ESC: {bye();closegraph(); exit(0);} case BACK : {back();p2del();p1turn();p1move();} } } ③ back() /*悔棋功能*/ { setcolor(6); setfillstyle(1,6); circle(getx(),gety(),9); floodfill(getx(),gety(),6); /*通过将现有棋子覆盖与棋盘底色相同的颜色来实现*/ setcolor(14) ; line(getx()-9,gety(),getx()+9,gety()) ; 因为覆盖棋盘颜色后对应的棋谱线条颜色被覆盖,所以通过画线函数补回被覆盖负分的线色 line(getx(),gety()-9,getx(),gety()+9) ; } 3.3胜负判断模块 ① win() /*胜负判断主程序*/ { for(i=120;i<540;i=i+20) for(j=50;j<470;j=j+20)/*通过循环扫描整个棋盘判定胜负*/ { if((a[i][j]+a[i+20][j]+a[i+40][j]+a[i+60][j]+a[i+80][j]==5)||(a[i][j]+a[i][j+20]+a[i][j+40]+a[i][j+60]+a[i][j+80]==5)|| (a[i][j]+a[i+20][j+20]+a[i+40][j+40]+a[i+60][j+60]+a[i+80][j+80]==5)||(a[i][j+80]+a[i+20][j+60]+a[i+40][j+40]+a[i+60][j+20]+a[i+80][j]==5)) /*如果棋盘上任何位置数组对应的值之和为5,则白方5子连珠*/ { if(a[i][j]+a[i+20][j]+a[i+40][j]+a[i+60][j]+a[i+80][j]==5) { moveto(i,j); green();delay(10000);moveto(i+20,j);green(); delay(10000);moveto(i+40,j);green();delay(10000);moveto(i+60,j);green();delay(10000);moveto(i+80,j);green();delay(10000); } else if(a[i][j]+a[i][j+20]+a[i][j+40]+a[i][j+60]+a[i][j+80]==5) { moveto(i,j); green();delay(10000);moveto(i,j+20);green(); delay(10000);moveto(i,j+40);green();delay(10000);moveto(i,j+60);green();delay(10000);moveto(i,j+80);green();delay(10000); } else if(a[i][j]+a[i+20][j+20]+a[i+40][j+40]+a[i+60][j+60]+a[i+80][j+80]==5) {moveto(i,j); green();delay(10000);moveto(i+20,j+20);green(); delay(10000);moveto(i+40,j+40);green();delay(10000);moveto(i+60,j+60);green();delay(10000);moveto(i+80,j+80);green();delay(10000); } else if(a[i][j+80]+a[i+20][j+60]+a[i+40][j+40]+a[i+60][j+20]+a[i+80][j]==5) {moveto(i,j+80); green();delay(10000);moveto(i+20,j+60);green(); delay(10000);moveto(i+40,j+40);green();delay(10000);moveto(i+60,j+20);green();delay(10000);moveto(i+80,j);green();delay(10000); } delscore1();p1_point_input2();p1_point_output() ; p1win(); } if((a[i][j]+a[i+20][j]+a[i+40][j]+a[i+60][j]+a[i+80][j]==0)||(a[i][j]+a[i][j+20]+a[i][j+40]+a[i][j+60]+a[i][j+80]==0)|| (a[i][j]+a[i+20][j+20]+a[i+40][j+40]+a[i+60][j+60]+a[i+80][j+80]==0)||(a[i][j+80]+a[i+20][j+60]+a[i+40][j+40]+a[i+60][j+20]+a[i+80][j]==0)) { if(a[i][j]+a[i+20][j]+a[i+40][j]+a[i+60][j]+a[i+80][j]==0) { moveto(i,j); green();delay(10000);moveto(i+20,j);green(); delay(10000);moveto(i+40,j);green();delay(10000);moveto(i+60,j);green();delay(10000);moveto(i+80,j);green();delay(10000); } else if(a[i][j]+a[i][j+20]+a[i][j+40]+a[i][j+60]+a[i][j+80]==0) { moveto(i,j); green();delay(10000);moveto(i,j+20);green(); delay(10000);moveto(i,j+40);green();delay(10000);moveto(i,j+60);green();delay(10000);moveto(i,j+80);green();delay(10000); } else if(a[i][j]+a[i+20][j+20]+a[i+40][j+40]+a[i+60][j+60]+a[i+80][j+80]==0) {moveto(i,j); green();delay(10000);moveto(i+20,j+20);green(); delay(10000);moveto(i+40,j+40);green();delay(10000);moveto(i+60,j+60);green();delay(10000);moveto(i+80,j+80);green();delay(10000); } else if(a[i][j+80]+a[i+20][j+60]+a[i+40][j+40]+a[i+60][j+20]+a[i+80][j]==0) {moveto(i,j+80); green();delay(10000);moveto(i+20,j+60);green(); delay(10000);moveto(i+40,j+40);green();delay(10000);moveto(i+60,j+20);green();delay(10000);moveto(i+80,j);green();delay(10000); } delscore2(); p2_point_input2();p2_point_output() ;p2win(); } } } ② p1win() { setcolor(15) ; settextstyle(0,0,2); 此处2个函数用于1p或2p获胜后的告知以及询问是否开始新的一局,调用restart();函数以继续或退出。 outtextxy(10,110,"1p win"); outtextxy(240,460,"Restart?(Y/N)"); restart(); } p2win() { setcolor(15) ; settextstyle(0,0,2); outtextxy(535,110,"2p win"); outtextxy(240,460,"Restart?(Y/N)"); restart(); } ③ restart() { 通过对键盘的操作,提取Y或N以确定是否开始新的一局。 switch(bioskey(0)) {case Y: {main();} case N: {bye();closegraph(); exit(0);} default:restart(); } } ④ initialization() { for(i=120;i<540;i++) for(j=50;j<470;j++) /*循环初始化棋盘对应的数组所在位置值为6*/ { a[i][j]=6; } } 3.4 文件操作模块 point() /*用于整合所有计分的函数,方便操作*/ 之所以做这么多函数来实现文件操作的计分,是因为我发现C语言中对文件操作似乎存在bug,如果放在一个函数中经常出现文件无法正常读取,无法正常写入等现象,即使拆分成如此多函数,也依旧偶尔会出现以上提到的一些小bug。 { p1_point_input(); p1_point_output() ; p2_point_input(); p2_point_output() ; } p1_point_input() /*1p计分文件读取*/ 首先打开文件,然后取出里面的数字赋值于ch变量,再用另一个函数打开文件并对ch进行自增操作,最后将ch写入文件。 { FILE *fp; fp=fopen("score1.txt","r"); ch=getw(fp); fclose(fp); } p1_point_input2() /*1p计分文件输入*/ { FILE *fp; fp=fopen("score1.txt","r+"); ch=ch+1; putw(ch,fp); fclose(fp); } p1_point_output() /*1p计分输出*/ { int i=0; char sh,score[10]; FILE *fp; 通过再次打开文件,循环扫描,输出文件中的数值并设置其样式。 fp=fopen("score1.txt", "r"); for(; (sh=fgetc(fp))!=EOF; ) { score[i++]=sh; } score[i]='\0'; setcolor(12); settextstyle(3,0,4); outtextxy(40,320,"score"); outtextxy(55,340,score); fclose(fp); } p2_point_input() 玩家2的计分模块,和玩家1的相同,就不再重复介绍了。 { FILE *fp; fp=fopen("score2.txt","r"); dh=getw(fp); fclose(fp); } p2_point_input2() { FILE *fp; fp=fopen("score2.txt","r+"); dh=dh+1; putw(dh,fp); fclose(fp); } p2_point_output() { int i=0; char fh,score[10]; FILE *fp; fp=fopen("score2.txt", "r"); for(; (fh=fgetc(fp))!=EOF; ) { score[i++]=fh; } score[i]='\0'; setcolor(12); settextstyle(3,0,4); outtextxy(560,320,"score"); outtextxy(575,340,score); fclose(fp); 依旧通过循环读取文件内比分,然后通过颜色覆盖从而达到分数改变功能,这么操作十分复杂,体现了C语言图形编程下的不完善性。 delscore1() /*删除当前1p分数*/ { int i=0; char sh,score[10]; FILE *fp; fp=fopen("score1.txt", "r"); for(; (sh=fgetc(fp))!=EOF; ) { score[i++]=sh; } score[i]='\0'; setcolor(0); settextstyle(3,0,4); outtextxy(40,320,"score"); outtextxy(55,340,score); fclose(fp); } delscore2() /*删除当前2p分数*/ { int i=0; char fh,score[10]; FILE *fp; fp=fopen("score2.txt", "r"); for(; (fh=fgetc(fp))!=EOF; ) { score[i++]=fh; } score[i]='\0'; setcolor(0); settextstyle(3,0,4); outtextxy(560,320,"score"); outtextxy(575,340,score); } 4、程序设计总结 经过这次课程设计,我发现在很多地方的知识都不足,很多函数和技巧都要从网络上或其他书籍上找,可能学计算机要看看很多很多书,尤其在大学,很多情况下都需要自学,我想在以后的学习和实践工作中,会多读多看多练的,努力让自己的实力得到提高,在这个小游戏中,不能调用鼠标,只能通过输入坐标点位置,这是一个很大的不足,以后学习了一定要修改的更好! 5、参考文献 [1] 湛为芳.C语言程序设计技术.清华大学出版社,2006 [2] 谭浩强.C程序设计(第三版).清华大学出版社,2005 [3] Kennth A.reek. C和指针 (徐波译) [4] 另外还使用了百度中文搜索引擎
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服