完整版基于C语言的五子棋程序毕业课程设计报告.docx
《完整版基于C语言的五子棋程序毕业课程设计报告.docx》由会员分享,可在线阅读,更多相关《完整版基于C语言的五子棋程序毕业课程设计报告.docx(18页珍藏版)》请在冰豆网上搜索。
完整版基于C语言的五子棋程序毕业课程设计报告
石家庄铁道学院课程设计
基于C语言的五子棋程序课程设计
单位:
数0901分院(系)
专业:
数学与应用数学
学号:
学生姓名:
许晓倩
指导教师:
石玉晶
完成日期2010年07月14日
摘要
本程序是一款棋类益智游戏程序,与五子棋游戏相近,是由C语言编写的可在WINDOWS系统下运行的娱乐游戏平台。
该程序面向广大棋类游戏的爱好者,能够提供方便,实现基本智能控制的游戏环境。
本程序可以实现人人对战,用户可以根据需要自行选择不同维数的棋盘。
对战中,为方便双方棋手,采用键盘上的上下左右键控制棋子的上下左右移动,由空格键控制下棋,双方都可通过ESC键终止游戏。
游戏开始后,红、白双方轮流下棋,程序会根据双方下棋的先后顺序自动显示不同颜色的棋子,提示当前下棋的棋手,任何一方由三子连成一线时,游戏结束,结束时会显示对战双方胜负情况。
关键词:
五子棋游戏应用程序,C语言,图形函数。
1.选题的意义4
2.系统功能需求分析
2.1设计思想-5
2.2功能模块-5
2.3流程图说明6
3.系统设计---7
3.1流程图---7
3.2数据结构-7
3.3中心算法代码说明v
4.系统实现---9
4.1程序代码--9
4.2系统使用--24
4.3运行效果说明4
5.总结
5.1设计收获--25
5.2存在的主要问题
5.3参考文献--25
第1章选题的意义
总的来说,通过五子棋的设计,能使我掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能并熟悉分支、循环、数组、函数等的综合运用。
这次课程设计我们在学习了C语言之后第一次一个人设计程序,以前在完成作业时虽然也写程序,但当时的程序通常都是很短的,涉及到的知识点也通常比较单一。
这次的课程设计则是对我们这半年学习的C语言的中分支、循环、数组、函数等知识的综合运用,也是对我们所学知识的一个综合考察。
在运用这些知识的时候也锻炼了软件开发所需要的问题分析、系统设计、程序编码、测试等基本方法和技能,为我们以后从事软件开发打下基础。
另外,在这个五子棋游戏的设计过程中还会涉及到我们在C语言课堂上没有涉及到的图形设计,这又未尝不是一个学习新知识的好机会。
我希望自己通过查阅资料,在编写程序,调试程序的过程中,独立掌握这一知识,并将它正确运用到我的程序中来。
其次,五子棋是一款非常简单的棋类游戏,我从小学六年级就就开始玩五子棋,那时候用的还是自己画的棋盘,到大学有了更多的充裕时间,我开始经常的玩QQ游戏中的五子棋,对五子棋浓厚的兴趣使我在看到这一课题的时候马上选择了它,虽然五子棋游戏的应用程序已经普遍,但身为棋迷的我希望将自己所学的知识应用到五子棋游戏中,设计出一款我自己的五子棋。
第2章系统功能需求分析
2.1设计思想
该系统为五子棋应用程序的简版,功能上要求玩家可以自己选择3到9维的棋盘,玩家通过键盘上的上下左右键来实现棋子的移动,通过空格键输入棋子,每一步都可以通过ESC键,退出游戏,当一方三子连成一线时,这一方赢棋,并结束游戏。
2.2功能模块
分析:
程序总共包括5个模块,分别是初始化棋盘模块,判断结果模块,键盘功能控制模块,流程控制模块。
初始化棋盘模块:
该模块的主要功能是根据玩家的选择初始化棋盘维数。
键盘功能控制模块:
该模块根据玩家输入的上下左右键来控制棋盘上棋子的移动,根据enter键控制棋子的输入。
判断结果模块:
该模块的功能是根据玩家输入的棋盘上的棋子,判定是否某一方存在三子连成一线。
游戏控制模块:
该模块用来控制游戏的开始,在任意阶段任一方按ESC结束游戏,任一方三子连成一线,该方赢棋,输出结果,结束游戏。
流程控制模块:
控制整个程序的运行,包括开始,结束以及各个模块的运行顺序各个函数之间的调用。
2.3功能结构图
第3章系统设计
3.1流程图
ESC
ESC
ESC
ESC
按任意键
是
否
3.2数据结构
程序在windows界面中建立坐标系,棋盘初始点x1,y1,x2,y2,棋盘维数n,棋格宽度规定为120,以step_x,step_y,为棋子小坐标乘以棋盘宽度后为棋子坐标。
3.3中心算法代码说明
程序要求使用者自己输入棋盘维数为实现这一功能,主函数中使用语句printf(“Pleasechooseaqipanbetween3and9:
”);使用者输入数字后,使用语句scanf(“%d”,&n);再调用函数printf_qipan(intn)。
printf_qipan(intn)中,建立一个图形窗口,建立坐标系,以n为变量,输出3到9维棋盘。
程序要求使用者能够通过键盘来控制棋子的移动和输入,judge_key(intx,inty)设置了键盘功能。
通过定义
#defineLEFT0x4b00
#defineRIGHT0x4d00
#defineDOWN0x5000
#defineUP0x4800
#defineESC0x011b
#defineSPACE0x3920
将键转化为C语言可以读取的字符,通过调用函数judge_key(intx,inty),按上下左右键,对应位置输出对应色圆环,前一位置画背景颜色圆环,覆盖红或白圆环,达到棋子的移动的效果;按空格键画实心圆,并根据step_x,step_y的取值取得此时的棋子坐标的坐标;按ESC结束程序。
程序中规定某一方有三个字连成一线时,这一方赢棋。
函数judge_result(intx,inty,intn)用来判断哪方赢棋,
在每次输入空格键后,调用此函数,分别查看这一位置的上下/左右/斜方向上和这一棋子颜色相同的棋子是否有三个,若有,该方赢棋,然后输出结果,结束程序,若没有,继续游戏。
第4章系统实现
4.1程序代码
源程序代码为
#include
#include
#include
#include
#include
#defineLEFT0x4b00
#defineRIGHT0x4d00
#defineDOWN0x5000
#defineUP0x4800
#defineESC0x011b
#defineSPACE0x3920
#defineCELL30
#defineJZ4
#defineJS3
#definer10
intbox[12][12];
intstep_x,step_y;
intkey;
intflag=1;
voidprintf_qipan(intn);
voidprintf_qizi(intx,inty);
voidchange();
voidjudge_who(intx,inty);
voidjudge_key(intn);
intjudge_result(intx,inty,intn);
voidattentoin();
voidattention()
{
charch;
window();
textbackground(WHITE);
textcolor(BLACK);
clrscr();
gotoxy(15,4);
printf("PlayRules:
");
gotoxy(15,8);
printf("1.PressLeft,Right,Up,DownKeytomovePiece");
gotoxy(15,12);
printf("2.PressSpacetoplacethePiece");
gotoxy(15,16);
printf("3.DONOTpressSpaceoutsideofthechessboard");
gotoxy(15,20);
printf("DoyouaccepttheabovePlayingRules?
[Y/N]:
");
while
(1)
{
gotoxy(60,20);
ch=getchar();
if(ch=='Y'||ch=='y')
break;
elseif(ch=='N'||ch=='n')
{
window();
textbackground(WHITE);
textcolor(BLACK);
clrscr();
exit(0);
}
gotoxy(51,12);
printf("");
}
}
voidprintf_qipan(intn)
{
intx1,x2,y1,y2;
setbkcolor(BLUE);
setcolor(RED);
gotoxy(5,2);
printf("Left,Right,Up,DownKEYtomove,Spacetoput,ESC-quit.");
for(x1=1,y1=1,y2=n;x1<=n;x1++)
line((x1+JZ)*CELL,(y1+JS)*CELL,(x1+JZ)*CELL,(y2+JS)*CELL);
for(x1=1,y1=1,x2=n;y1<=n;y1++)
line((x1+JZ)*CELL,(y1+JS)*CELL,(x2+JZ)*CELL,(y1+JS)*CELL);
for(x1=1;x1<=n;x1++)
for(y1=1;y1<=n;y1++)
box[x1][y1]=0;
}
voidprintf_qizi(intx,inty)
{
if(flag==1)
{
setcolor(RED);
setlinestyle(SOLID_LINE,0,1);
x=(x+JZ)*CELL;
y=(y+JS)*CELL;
circle(x,y,r);
setfillstyle(1,RED);
sector(x,yr,r);
}
if(flag==2)
{
setcolor(WHITE);
setlinestyle(SOLID_LINE,0,1);
x=(x+JZ)*CELL;
y=(y+JS)*CELL;
circle(x,y,r);
setfillstyle(1,WHITE);
sector(x,yr,r);
}
}
voidjudge_key(intn)
{
inti;
intj;
switch(key)
{
caseLEFT:
{
if(step_x-1<1)
break;
else
{
for(i=step_x-1,j=step_y;i>=1;i--)
if(box[i][j]==0)
{
circle(step_x,step_y,r);
break;
}
if(i<1)break;
step_x=i;
judge_who(step_x,step_y);
setcolor(BLUE);
circle((step_x+1+JZ)*CELL,(step_y+JZ)*CELL,r);
break;
}
caseRIGHT:
if(step_x+1>n+1)
break;
else
{
for(i=step_x+1,j=step_y;iif(box[i][j]==0)
{
circle(step_x,step_y,r);
break;
}
if(i>n+1)
break;
step_x=i;
judge_who(step_x,step_y);
setcolor(BLUE);
circle((step_x-1+JZ)*CELL,(step_y+JZ)*CELL,r);
break;
}
}
caseDOWN:
if(step_y+1>n+1)
break;
else
{
for(i=step_x,j=step_y+1;j<=n;j++)
if(box[i][j]==0)
{
circle(step_x,step_y,r);
break;
}
if(j>n)break;
step_y=j;
judge_who(step_x,step_y);
setcolor(BLUE);
circle((step_x+JZ)*CELL,(step_y-1+JZ)*CELL,r);
break;
}
caseUP:
if(step_y<-3)
break;
else
{
for(i=step_x,j=step_y-1;j>=-2;j--)
if(box[i][j]==0)
{
circle(step_x,step_y,r);
break;
}
if(j<0)break;
step_y=j;
judge_who(step_x,step_y);
setcolor(BLUE);
circle((step_x+JZ)*CELL,(step_y+1+JZ)*CELL,r);
break;
}
caseESC:
break;
caseSPACE:
if(step_x>0&&step_x<=n+2&&step_y>=0&&step_y<=n+2)
{
if(box[step_x][step_y]==0)
{
printf_qizi(step_x,step_y+1);
box[step_x][step_y]=flag;
if(judge_result(step_x,step_y,n)==1)
{
gotoxy(30,4);
if(flag==1)
{
setbkcolor(BLACK);
cleardevice();
setviewport(380,1);
/*定义一个图形窗口*/
setfillstyle(1,2);
/*绿色以实填充*/
setcolor(RED);
rectangle();
floodfill();
setcolor(12);
settextstyle(1,0,5);
/*三重笔划字体,水平放?
5倍*/
outtextxy(20,20,"TheREDWin!
");
setcolor(15);
settextstyle(3,0,5);
/*无衬笔划字体,水平放大5倍*/
outtextxy("TheREDWin!
");
setcolor(14);
settextstyle(2,0,8);
getch();
closegraph();
exit(0);
}
if(flag==2)
{
setbkcolor(WHITE);
cleardevice();
setviewport(380,1);
/*定义一个图形窗口*/
setfillstyle(1,2);
/*绿色以实填充*/
setcolor(RED);
rectangle();
floodfill();
setcolor(12);
settextstyle(1,0,5);
/*三重笔划字体,水平放大8倍*/
outtextxy(20,20,"TheWHITEWin!
");
setcolor(15);
settextstyle(3,0,5);
/*无衬笔划字体,水平放大5倍*/
outtextxy("TheWHITEWin!
");
setcolor(14);
settextstyle(2,0,8);
getch();
closegraph();
exit(0);
}
}
change();
break;
}
}
else
break;
}
}
voidchange()
{
if(flag==1)
flag=2;
else
flag=1;
}
voidjudge_who(intx,inty)
{
if(flag==1)
setcolor(RED);
circle((x+JZ)*CELL,(y+JZ)*CELL,r);
if(flag==2)
setcolor(WHITE);
circle((x+JZ)*CELL,(y+JZ)*CELL,r);
}
intjudge_result(intx,inty,intn)
{
intj,k,n1,n2;
while
(1)
{
n1=0;
n2=0;
/*水平向左数*/
for(j=x,k=y;j>=1;j--)
{
if(box[j][k]==flag)
n1++;
else
break;
}
/*水平向右数*/
for(j=x,k=y;j{
if(box[j][k]==flag)
n2++;
else
break;
}
if(n1+n2-1>=3)
{
return
(1);
break;
}
/*垂直向上数*/
n1=0;
n2=0;
for(j=x,k=y;k>=0;k--)
{
if(box[j][k]==flag)
n1++;
else
break;
}
/*垂直向下数*/
for(j=x,k=y;k<=n;k++)
{
if(box[j][k]==flag)
n2++;
else
break;
}
if(n1+n2-1>=3)
{
return
(1);
break;
}
/*向左上方数*/
n1=0;
n2=0;
for(j=x,k=y;j>=1,k>=0;j--,k--)
{
if(box[j][k]==flag)
n1++;
else
break;
}
/*向右下方数*/
for(j=x,k=y;j<=n,k<=n+1;j++,k++)
{
if(box[j][k]==flag)
n2++;
else
break;
}
if(n1+n2-1>=3)
{
return
(1);
break;
}
/*向右上方数*/
n1=0;
n2=0;
for(j=x,k=y;j<=n+1,k>=0;j++,k--)
{
if(box[j][k]==flag)
n1++;
else
break;
}
/*向左下方数*/
for(j=x,k=y;j>=1,k<=n;j--,k++)
{
if(box[j][k]==flag)
n2++;
else
break;
}
if(n1+n2-1>=3)
{
return
(1);
break;
}
return(0);
break;
}
}
voidmain()
{
intgdriver=VGA,gmode=VGAHI;
intn;
clrscr();
attention();
window();
textbackground(WHITE);
textcolor(BLACK);
clrscr();
gotoxy(15,10);
printf("Pleasechoseaqipanbetween3and9:
");
scanf("%d",&n);
initgraph(&gdriver,&gmode,"c:
\\tc");
/*setwritemode(XOR_PUT);*/
flag=1;
printf_qipan(n);
do
{
step_x=0;
step_y=0;
/*printf_qizi(step_x,step_y,8);*/
judge_who(step_x-1,step_y-1);
do
{
while(bioskey
(1)==0);
key=bioskey(0);
judge_key(n);
}
while(key!
=SPACE&&key!
=ESC);
}
while(key!
=ESC);
closegraph();
}
4.2系统使用
该系统是C语言编写的,在TC环境下运行,在TC环境下打开后,按Ctrl+F9运行程序,输入Y/y接受规则继续游戏,选择所需棋盘维数,输入n/N退出游戏,游戏过程中上方显示具体操作,任一方三子连成一线,该方胜出,按任意键结束程序。
4.3运行效果说明
该程序基本可以实现所要求的功能。
第5章总结
5.1设计收获
通过这个程序的设计我学到了很多图形函数的使用方法,也了解到在设计程序中逻辑性很重要,没有一个合理的,可行的,清晰地逻辑关系也就无法做出一个具有所需功能的程序。
5.2设计中遇到的困难和问题
在设计初期,我甚至不能再窗口上画出一条直线,却怎么也检查不出来错误,后来才知道是所定义的颜色在当前背景下不能显示,当我能够画出棋盘并画棋子时,发现棋子的轨迹留在棋盘上,同样颜色的棋子再次从那儿移动的时候就无法显示出来,在网上问了一下才知道可以用背景颜色覆盖。
5.3主要参考文献
1.《C语言程序设计实例精粹》.谭明金.电子工业出版社
2.《C语言编程技巧及实用程序荟萃》.鲁沐浴.电子工业出版社
3.《C语言课程设计案例精选与编程指导》陈清华.东南大学出版社
4.《C语言课程设计案例精编》.郭翠英.中国水利水电出版社
5.《C语言实战105例》.王为青.人民邮电出版社