C语言五子棋源代码设计报告.docx
《C语言五子棋源代码设计报告.docx》由会员分享,可在线阅读,更多相关《C语言五子棋源代码设计报告.docx(27页珍藏版)》请在冰豆网上搜索。
C语言五子棋源代码设计报告
C语言程序设计综合实验
设计报告
题目:
五子棋
班级;07电气
(1)班
人数:
4人
小组成员:
时间:
1课程设计报告
1.1课题描述
1.2需求分析
1.3概要设计
2源程序代码
3详细设计
1.课题设计报告
1.1课题分析:
游戏介绍:
在一个18*18的方格中下棋,两个玩家,根据键盘上的上、下、左、右键及W、S、A、D来控制棋的走向,空格键及回车键表示确定棋子的落下位置,两个玩家为交替下棋,如果于其中任何一家下的五个棋子能够练成一线那么为胜者,游戏结束。
1、五子棋是两个人之间进行的竞技活动,开始是由P1先下,把棋落在方框内,然后P2下,如此下棋直到一方在棋盘的横,竖,斜将同色的五个棋子连成一条线,则此方获胜。
游戏由玩家决定继续或结束。
1.2需求分析
(1)在游戏开始时出现一个欢迎的界面同时介绍了游戏的规则;
(2)画出棋盘的大小;
(3)画棋子并确定棋子的大小;
(4)判断键盘输入哪个键执行操作;
(5)玩家P1先落棋;
(6)玩家轮流下棋;
(7)判断赢家。
(8)由玩家决定是否继续新游戏。
1.3概要设计
(1)功能模块
2.主流程图
遇到的一个问题:
图形一闪而过解决方法
因为Win-TC的图形驱动程序EGAVGA.BGI文件安装路径为c:
\\Win-TC\\projects
intgdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"c:
\\tc")改为initgraph(&gdriver,&gmode,"c:
\\Win-TC\\projects")
2程序代码
#include
#include"stdio.h"
#include"graphics.h"
/*定义1号玩家的操作键键码*/
#defineW0x1177/*上移--'W'*/
#defineS0x1f73/*下移--'S'*/
#defineA0x1e61/*左移--'A'*/
#defineD0x2064/*右移--'D'*/
#defineSP0x3920/*落子--空格键*/
/*定义2号玩家的操作键键码*/
#defineUP0x4800/*上移--方向键up*/
#defineDOWN0x5000/*下移--方向键down*/
#defineLEFT0x4b00/*左移--方向键left*/
#defineRIGHT0x4d00/*右移--方向键right*/
#defineENTER0x1c0d/*落子--回车键Enter*/
#defineESC0x011b
#defineX(getx()-140)/20/*将棋盘上光标所在点的横坐标X转化为0-18的数*/
#defineY(gety()-70)/20/*将棋盘上光标所在点的横坐标Y转化为0-18的数*/
intk,w=DETECT,gmode,j,i;
inta[20][20];
voidp1move();/*定义函数*/
voidp2move();
voidwin();
p1win();
p2win();
yellow();
white();
black();
heqi();
welcome();
help();
csz();
qipang();
p1turn();
p2turn();
p1del();
p1turn()/*画左上角的白棋*/
{
setcolor(7);
setfillstyle(1,7);
circle(60,110,9);
floodfill(60,110,7);
}
p1del()/*将左上角白棋檫去*/
{
setfillstyle(1,14);
floodfill(60,110,14);
}
p2turn()/*画右上角的黑棋*/
{
setcolor(0);
setfillstyle(1,0);
circle(578,115,9);
floodfill(578,115,0);
}
p2del()/*画右上角的黑棋*/
{
setfillstyle(1,14);
floodfill(578,115,14);
}
white()/*在当前位置画白棋*/
{
setcolor(7);
setfillstyle(1,7);
circle(getx(),gety(),9);
floodfill(getx(),gety(),7);
}
black()/*在当前位置画黑棋*/
{
setcolor(0);
setfillstyle(1,0);
circle(getx(),gety(),9);
floodfill(getx(),gety(),0);
}
yellow()/*补棋盘的颜色*/
{
setcolor(6);
setfillstyle(1,6);
circle(getx(),gety(),9);
floodfill(getx(),gety(),6);
setcolor(15);
line(getx()-9,gety(),getx()+9,gety());
line(getx(),gety()+9,getx(),gety()-9);
}
qipang()/*画棋盘*/
{setfillstyle(1,6);
bar(120,50,520,450);
setfillstyle(1,14);
bar(540,50,620,150);
bar(20,50,100,150);
for(k=0;k<19;k++)
{moveto(140+20*k,70);linerel(0,360);
moveto(140,70+20*k);linerel(360,0);
}
moveto(240,170);
setcolor(5);
settextstyle(3,0,4);
outtextxy(50,60,"P1");
outtextxy(560,60,"P2");
}
welcome()/*欢迎界面*/
{initgraph(&w,&gmode,"c:
\\Win-TC\\projects");
clearviewport();
setcolor(4);
settextstyle(0,0,6);
outtextxy(180,180,"Welcome");
settextstyle(0,0,2);
outtextxy(280,440,"pressanykeytobegin");
}
help()/*帮助界面*/
{
initgraph(&w,&gmode,"c:
\\Win-TC\\projects");
clearviewport();
setcolor(4);
settextstyle(0,0,2);
outtextxy(80,100,"P1move;'WSAD'");
outtextxy(80,120,"set:
space");
outtextxy(80,180,"P2move:
updownleftright");
outtextxy(80,200,"set:
Enter");
outtextxy(80,280,"Whoeverisfirsttogatherfive");/*samecolorpiecesinalinewithoutanydifferentcolorpieceamongthem,thenhewin*/
outtextxy(80,300,"samecolorpiecesinalinewithout");
outtextxy(80,320,"anydifferentcolorpieceamong");
outtextxy(80,340,"them,thenhewin.");
outtextxy(80,360,"Whenyouwanttoquitthegame,");
outtextxy(80,380,"pressEsc.");
outtextxy(220,440,"pressanykeytocontinue");
while(bioskey
(1)==0);
}
p1win()/*玩家1获胜界面*/
{
initgraph(&w,&gmode,"c:
\\Win-TC\\projects");
clearviewport();
setcolor(4);
settextstyle(0,0,6);
outtextxy(180,180,"P1WIN");
settextstyle(0,0,2);
outtextxy(280,440,"pressanykeytobegin");
while(bioskey
(1)==0);
main();
}
p2win()/*玩家2获胜界面*/
{
clearviewport();
setcolor(4);
settextstyle(0,0,6);
outtextxy(180,180,"P2WIN");
settextstyle(0,0,2);
outtextxy(280,440,"pressanykeytobegin");
while(bioskey(0)!
=0)main();
}
heqi()/*和棋界面*/
{
clearviewport();
setcolor(4);
settextstyle(0,0,6);
outtextxy(180,180,"tie");
settextstyle(0,0,2);
outtextxy(280,440,"pressanykeytobegin");
while(bioskey(0)!
=0)main();
}
csz()/*将所在位置的A[X][Y]赋初值6*/
{
for(i=0;i<19;i++)
for(j=0;j<19;j++)
{a[i][j]=6;}
}
voidwin()/*判断输赢*/
{intsum1,sum2,sum3,sum4,sum=0,n,i,j;
for(i=X-4,j=Y-4,n=0;i<=X,j<=Y;i++,j++,n-=2)
{sum1=a[i][Y]+a[i+1][Y]+a[i+2][Y]+a[i+3][Y]+a[i+4][Y];
sum2=a[i][j]+a[i+1][j+1]+a[i+2][j+2]+a[i+3][j+3]+a[i+4][j+4];
sum3=a[X][j]+a[X][j+1]+a[X][j+2]+a[X][j+3]+a[X][j+4];
sum4=a[i][j+8+n]+a[i+1][j+7+n]+a[i+2][j+6+n]+a[i+3][j+5+n]+a[i+4][j+4+n];
if(sum1==5||sum2==5||sum3==5||sum4==5)
p2win();
if(sum1==0||sum2==0||sum3==0||sum4==0)
p1win();}
for(i=0;i<18;i++)
for(j=0;j<18;j++)
sum=sum+a[i][j];
if(sum<181)
heqi();
}
voidp1move()/*玩家1的移动*/
{
switch(bioskey(0))
{
caseESC:
{closegraph();exit(0);}/*如果按键为ESC就退出游戏*/
caseSP:
/*落子*/
if(a[X][Y]==6){p1del();p2turn();a[X][Y]=0;white();win();p2move();}
elsep1move();
caseA:
/*向左移*/
if(a[X][Y]==0)
{if(getx()==140)moveto(520,gety());moverel(-20,0);white();}
elseif(a[X][Y]==1)
{if(getx()==140)moveto(520,gety());black();moverel(-20,0);white();}
else
{yellow();if(getx()==140)moveto(520,gety());moverel(-20,0);white();}p1move();
caseD:
/*向右移*/
if(a[X][Y]==0){if(getx()==500)moveto(120,gety());moverel(20,0);white();}
elseif(a[X][Y]==1){if(getx()==500)moveto(120,gety());black();moverel(20,0);white();}
else{yellow();if(getx()==500)moveto(120,gety());moverel(20,0);white();}p1move();
caseW:
/*向上移*/
if(a[X][Y]==0){if(gety()==70)moveto(getx(),450);moverel(0,-20);white();}
elseif(a[X][Y]==1){if(gety()==70)moveto(getx(),450);black();moverel(0,-20);white();}
else{yellow();if(gety()==70)moveto(getx(),450);moverel(0,-20);white();}p1move();
caseS:
/*向下移*/
if(a[X][Y]==0){if(gety()==430)moveto(getx(),50);moverel(0,20);white();}
elseif(a[X][Y]==1){if(gety()==430)moveto(getx(),50);black();moverel(0,20);white();}
else{yellow();if(gety()==430)moveto(getx(),50);moverel(0,20);white();}p1move();
default:
p1move();
}}
voidp2move()/*玩家2的移动*/
{
switch(bioskey(0))/*如果按键为ESC就退出游戏*/
{
caseESC:
{closegraph();exit(0);}
caseENTER:
/*落子*/
if(a[X][Y]==6){p2del();p1turn();a[X][Y]=1;black();win();p1move();}
elsep2move();
caseLEFT:
/*向左移*/
if(a[X][Y]==1){if(getx()==140)moveto(520,gety());moverel(-20,0);black();}
elseif(a[X][Y]==0){if(getx()==140)moveto(520,gety());if(getx()==140)moveto(500,gety());white();moverel(-20,0);black();}
else{yellow();if(getx()==140)moveto(520,gety());moverel(-20,0);black();}p2move();
caseRIGHT:
/*向右移*/
if(a[X][Y]==1){if(getx()==500)moveto(120,gety());moverel(20,0);black();}
elseif(a[X][Y]==0){if(getx()==500)moveto(120,gety());white();moverel(20,0);black();}
else{yellow();if(getx()==500)moveto(120,gety());moverel(20,0);black();}p2move();
caseUP:
/*向上移*/
if(a[X][Y]==1){if(gety()==70)moveto(getx(),450);moverel(0,-20);black();}
elseif(a[X][Y]==0){if(gety()==70)moveto(getx(),450);white();moverel(0,-20);black();}
else{yellow();if(gety()==70)moveto(getx(),450);moverel(0,-20);black();}p2move();
caseDOWN:
/*向下移*/
if(a[X][Y]==1){if(gety()==430)moveto(getx(),50);moverel(0,20);black();}
elseif(a[X][Y]==0){if(gety()==430)moveto(getx(),50);white();moverel(0,20);black();}
else{if(gety()==430)moveto(getx(),50);yellow();moverel(0,20);black();}p2move();
default:
p2move();
}
}
main()/*主函数*/
{welcome();/*调用欢迎界面*/
help();/*调用帮助界面*/
initgraph(&w,&gmode,"c:
\\Win-TC\\projects");/*清屏*/
clearviewport();
csz();
qipang();/*调用棋盘*/
p1move();/*调用玩家1的移动*/
p2move();
getch();
}
3详细设计
1部分:
以下是我负责的模块的函数,由于个人水平问题,我只负责画图部分。
(1)画白棋棋子
(white()
{
setcolor(7);
setfillstyle(1,7);
circle(getx(),gety(),9);
floodfill(getx(),gety(),7);
}
(2)画黑棋棋子
black()
{
setcolor(0);
setfillstyle(1,0);
circle(getx(),gety(),9);
floodfill(getx(),gety(),0);
}
(3)补棋盘颜色
由于我们实现棋子在棋盘上移动的功能是用:
某一色棋子覆盖棋盘上的点,当光标移动后,用白色圆圈将原本的棋子覆盖,再填上与棋盘相同的颜色,最后用十字线条覆盖原本棋子所在的位置,然后再用棋子覆盖棋盘上新的点实现移动棋子和下棋的功能的,所以需要我编此函数。
yellow()
{
setcolor(6);
setfillstyle(1,6);
circle(getx(),gety(),9);
floodfill(getx(),gety(),6);
setcolor(15);
line(getx()-9,gety(),getx()+9,gety());
line(getx(),gety()+9,getx(),gety()-9);
}
(4)画棋盘
这段函数的功能是画出棋盘及棋盘边左右上方的p1,p2字样。
首先先画一块18*18的有色方块,然后利用循环及相对坐标在方块上画出棋盘的竖线和横线,接着移出棋盘设置背景色,再设置字体颜色,最后再在棋盘的左右上方写上p1、p1。
qipang()
{setfillstyle(1,6);bar(120,50,520,450);
for(k=0;k<19;k++)
{moveto(140+20*k,70);linerel(0,360);
moveto(140,70+20*k);linerel(360,0);
}
moveto(240,170);
setbkcolor(14);
setcolor(5);
settextstyle(3,0,4);
outtextxy(50,60,"P1");
outtextxy(560,60,"P2");
}
课设总结
经过这次的选课,我最大的感觉就是遗憾,验证了一句话:
书到用时方恨少啊!
!
!
!
!
!
由于水平问题,我在这次的程序设计中承担的任务是画图。
。
。
。
令人郁闷的任务。
。
。
让我很后悔上学期没有把C学透,学好。
虽然我考了99,但我自己知道,那是突击出来的结果,实际上我肚子里的东西没多少。
还好,我的队友们水平都很不错,我们组才可以完成。
其实我是有尝试负责判断胜负的部分,可是程序写出来了,却怎么改都不行。
。
时间紧迫,其他3名组员毅然决定派给我另一个光荣而又神圣的任务——画棋盘。
至于画棋盘嘛,我的水平还够,完成得很快。
但是我并没有因此而闲着,我还帮助其他组员出谋划策,检测程序的完整性,以及排错,我还是有发挥自己的余光余热的,希望老师不要让我不过啊
2部分
voidp1move()/*玩家1的移动*/
{
switch(bioskey(0))
{
caseESC:
{closegraph();exit(0);}/*如果按键为ESC就退出游戏*/
caseSP:
/*落子*/
if(a[X][Y]==6){p1del();p2turn();a[X][Y]=0;white();win();p2move();}
elsep1move();
caseA:
/*向左移*/
if(a[X][Y]==0)
{if(getx()==140)moveto(520,gety());moverel(-20,0);white();}
elseif(a[X][Y]==1)
{if(getx()==140)moveto(520,gety());black();moverel(-20,0);white();}
else
{yellow();if(getx()==140)moveto(520,gety());moverel(-20,0);white();}p1move();
caseD:
/*向右移*/
if(a[X][Y]==0){if(getx()==500)moveto(120,gety());moverel(20,0);white();}
elseif(a[X][Y]==1){if(getx()==500)moveto(120,gety());black();moverel(20,0);white();}
else{yellow();if(getx()==500)moveto(120