C语言图形五子棋课程设计报告.docx
- 文档编号:26755466
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:36
- 大小:237.70KB
C语言图形五子棋课程设计报告.docx
《C语言图形五子棋课程设计报告.docx》由会员分享,可在线阅读,更多相关《C语言图形五子棋课程设计报告.docx(36页珍藏版)》请在冰豆网上搜索。
C语言图形五子棋课程设计报告
北京师范大学
C语言课程设计汇报
课题名称:
游戏五子棋
******
课题组员:
罗福莉赵帅帅何虹达
院系:
信息科学和技术
时间:
20XX.3.15-20XX.4.20
摘要
五子棋是一个两人对弈纯策略型棋类游戏,应用C语言编写程序能够在计算机上实现二人对弈五子棋功效。
二人对弈五子棋程序由欢迎界面显示、游戏界面生成、光标移动和落子、判定胜败、悔棋功效、提供音效等子程序组成;程序中应用了结构体、数组、全局变量、按键处理和图形编程等元素和语句。
程序经过棋盘和棋子图像生成、二人移子和落子和判定胜败等功效实现,在计算机上实现了二人五子棋对弈。
第1章:
需求分析
1.1五子棋背景
传统五子棋棋具和围棋相同,棋子分为黑白两色,棋盘为18×18,棋子放置于棋盘线交叉点上。
两人对局,各执一色,轮番下一子,先将横、竖或斜线5个或5个以上同色棋子连成不间断一排者为胜。
因为传统五子棋在落子后不能移动或拿掉,所以也能够用纸和笔来进行游戏。
1.2五子棋需求分析和步骤设计
本程序设计为人和人对弈,一方执黑棋,一方执白棋,轮番走棋,每方全部试图在游戏结束前让自己棋子五子相连,首先实现五子相连一方获胜。
程序实施过程中,要求棋盘、棋子时时可见,游戏界面有提醒信息轮到何方下棋,人能够经过按键盘按键移动光标,再点击enter键摆放棋子,而且每落一子全部有系统声音,创新之处是能够提供悔棋功效。
1.2.1程序需求分析
依据功效需求,将程序分为画面显示、玩家操作、音效提供、胜败判定五个模块,以下分析各模块需求。
画面显示模块:
程序开始运行时,显示制作者和给出欢迎及退出界面;游戏开始后要求生成18×18棋盘图像,并在棋盘上方显示欢迎信息“欢迎playour五子棋”,棋盘下方游戏显示应该轮到甲方或乙方落子,棋盘左右显示双方操作方法,进行过程中,要求实时显示棋盘上已落下棋子,甲方为白球,乙方为白圈;分出胜败后,要求给出游戏结束画面,而且问询用户是否需要继续游戏。
玩家操作模块:
程序开始时,需玩家确定选择“人人对战”后开始游戏;游戏过程中,两个玩家经过不一样按键移动光标,选择落子;游戏进行过程中,目前玩家下棋后,另一位玩家下棋前,目前玩家能够悔棋。
悔棋提醒在棋盘右下方,为按键“b”。
游戏结束时,有玩家选择是否开始新游戏。
音效提供模块:
玩家每落一子,系统提供音效一声,增加下棋趣味性。
胜败判定模块:
实时监测棋盘上棋子,一旦某一色棋子出现五子连线,终止游戏程序,并着色连成一线五子,棋盘下方弹出该色玩家胜出信息。
1.2.2程序步骤设计
依据程序需求分析结果,能够得出程序总体结构图图1,程序总体步骤图图2。
五子棋
图1五子棋总体结构图
Y
图2程序总体步骤图
第2章:
概要设计
2.1各类头文件和全局变量
#include
#include
#include
#include
intstartchoice;//
intwinner;//
intplayer;//
Q[200][200]={0};//Q数组统计旗子
charbutton;//读入键盘输入指令,如→
2.2画面显示模块
画面显示模块由欢迎界面,游戏棋盘界面,确定是否退出对话框界面,和感谢使用界面组成。
画面显示模块函数以下:
voidWelcome()//欢迎界面
voidDraw()//绘画游戏棋盘界面
voidClean()//清除—→运动轨迹
voidmenu_choose(charpress)//选择是否退出游戏对话框
voidPutDown()//显示落子函数
voidgoto_xy(intx,inty)//光标移动函数
画面效果图图3,4,5,6。
图3欢迎界面图
图4主菜单界面图
图5游戏界面图
图6确定退出对话框
第3章:
具体设计
3.1玩家操作模块
棋子移动和落子有键盘上按键控制,本程序选择甲乙双方按键全部为W、S、↑、↓、←、→和回车键,“b”,“ESC”,分别代表上移、下移、左移、右移光标和落子,悔棋,退出。
在光标移动过程中,光标根据玩家按键移动;在玩家按下落子按键后,程序自动调用棋子显示子程序和判定胜败子程序。
目前玩家下棋后,另一位玩家下棋前,目前玩家能够悔棋。
悔棋提醒在棋盘右下方,为按键“b”。
甲乙落子后,程序会为落子处数组元素赋一个特定值(玩家甲棋子赋为1,玩家乙棋子赋为2),用于判定胜败和悔棋。
玩家操作模块关键由以下函数组成:
voidRecord()//统计棋子情况
voidgo_back(intx1,inty1)//悔棋函数
voidPlay(charch)//读取键盘操作移动光标下棋和悔棋操作
3.2音效提供模块
为了提升游戏趣味性,我们为本游戏提供了简单系统音效。
程序语句很简单printf("\a");//'\a'表示蜂鸣声
3.3胜败判定模块
胜败判定模块是程序关键,该模块设计直接关系到程序运行速率和运行结果正确是否。
本函数依据每次落子位置,分别向上、下、左、右、左上、左下、右上、右下八个方向判定是否有相同颜色棋子连成五子,假如成立,游戏就结束,并显示提醒信息,不然继续落子。
以下简析本程序步骤:
由获胜条件能够知,经过判定行、列、斜边、反斜边方向上是否有连续5个子即可得出是否获胜结果。
在游戏开始时,将棋盘初始化,立即棋盘抽象为一个18*18数组,数组中每个元素数值设为0。
甲方落子时,将数组内对应坐标处元素赋值为2;乙方落子时,将数组内对应坐标处元素赋值为1。
经过循环扫描棋盘数组,经扫描后,如发觉在行、列、斜边、反斜边方向上有五个连续2,甲方获胜;如发觉在行、列、斜边、反斜边方向上有五个连续1,乙方获胜。
胜败判定模块关键由一个函数组成:
intJudge()//判定胜败函数
第4章:
调试分析
4.1图形模块
1.在图形模块中,因为是第一次使用,所以刚开始时对于棋盘创建位置把握有些欠缺。
处理方案:
参考书本和谷歌,找出最适宜位置坐标。
2.在构建棋子时候,发觉C语言中似乎对颜色处理有些错误,当棋谱线颜色为白色时,无法构建黑色棋子,只能画出白色棋子。
处理方案:
用白圈区分于白球,类似白子和黑子。
4.2玩家操作模块
1.在玩家操作模块中,出现最大问题之一就是棋盘已经有棋子地方还能够覆盖另一个棋子。
处理方案:
经过在PutDown()函数中添加if条件语句,判定假如所在位置对应数组值不等于0时,不能落子。
2.另一个问题就是之前提到,操作定位框时候会将定位框移到棋盘之外造成溢出。
处理方案:
经过if语句判定,假如操作框超出范围则移动到对应相反位置,比如移动棋盘最上端,若继续向上移动,则移动至棋盘最下端对应位置。
3.还有一个就是悔棋模块中,经过将现有棋子覆盖和棋盘底色相同颜色来覆盖后,棋谱线条部分也会被覆盖。
处理方案:
在go_back();即悔棋函数。
用棋谱线来覆盖棋子(比如:
┌└├等)。
4.3胜败判定模块
1.在胜败判定中一直没能想到好措施来数据化判定哪方玩家取得胜利。
处理方案:
经过参考书籍并加以优化,得出将棋谱做成数组,定义甲方落下为1,乙方落下为2,初始为0,这么即不会造成冲突,也很好处理了判定问题。
2.另一个问题在于一直不能优化代码做到不每次全部扫描整个棋盘来判定胜败。
处理方案:
至今还未处理,尝试过局部扫描,但失败了。
第5章:
用户手册
1.进入演示程序后,即显示欢迎界面,几秒后,按任何键进入菜单界面,再选择人人对战能够进入主界面开始游戏或选择退出键。
2.棋子移动和落子有键盘上按键控制,本程序选择甲乙方全部为↑、↓、←、→和回车键,分别代表上移、下移、左移、右移光标和落子。
在光标移动过程中,光标根据玩家按键移动;在玩家按下落子按键后,程序自动调用棋子显示子程序和判定胜败子程序。
3.在目前玩家按下落子按键后,程序自动调用棋子显示子程序和判定胜败子程序。
目前玩家下棋后,另一位玩家下棋前,目前玩家能够悔棋。
悔棋提醒在棋盘右下方,为按键“b”(即backspace)。
4.游戏中Esc键能够直接退出游戏。
5.游戏过程中,假如玩家1或玩家2有一方取得胜利后,程序自动将提醒哪一方取得了胜利,并能够选择是否继续新游戏。
6.游戏结束且玩家选择不再继续后,显示谢谢使用界面,再按任意键退出游戏。
第6章:
小组分工
组长:
罗福莉
组员:
赵帅帅,何虹达
具体分工:
组员
任务分工
罗福莉
汇报书写程序调试展示结果
赵帅帅
胜败判定设计主函数设计
何虹达
界面制作程序调试
第7章:
结论和心得
经过对各子程序设计和优化,本程序完成了五子棋软件主体设计和制作,基础达成了使用五子棋软件关键要求。
然而程序还有部分不足之处,首先,程序界面过于简陋,其次,判定胜后没有显示连成一线棋子是哪些,用户使用不便。
最终就是程序法实现人机对战,缺乏可玩性。
第8章:
源程序代码
//五子棋小游戏
#include
#include
#include
#include
intstartchoice,winner,player,Q[200][200]={0};//Q数组统计旗子
charbutton;//读入键盘输入指令,如→
structPoint//点坐标结构体
{
intx,y;
}point,game_xy;
structPiece//棋子坐标统计
{
structPointcoord;
structPiece*fore;
};
structPiece*head,*p,*ptr,*ptr1;
voidgoto_xy(intx,inty)//光标移动函数
{
COORDc;
c.X=2*x;
c.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
voidInit()//初始化函数,将统计棋子数组初始化
{
for(inti=0;i<200;i++)
for(intj=0;j<200;j++)
Q[i][j]=0;
startchoice=0;
player=1;
p=(structPiece*)malloc(sizeof(structPiece));
head=p;
}
voidWelcome()//欢迎界面
{
system("color2F");//#include
goto_xy(10,3);
printf("—→");
goto_xy(17,1);
printf("主菜单");
goto_xy(13,3);
printf("***人人对战***");
goto_xy(13,4);
printf("***退出***");
point.x=12;
point.y=3;
goto_xy(0,0);
}
voidShowWho()//显示轮到哪一方下棋
{
goto_xy(17,22);
if(player==0)
printf("轮到甲方落子");
else
printf("轮到乙方落子");
goto_xy(point.x,point.y);
}
voidDraw()//绘画游戏界面
{
game_xy.x=10;
game_xy.y=3;
system("cls");
system("color3F");//3湖蓝色F亮白色
goto_xy(15,1);
printf("欢迎playour五子棋!
");
/*goto_xy(29,22);
printf("重新开始r");*/
goto_xy(1,22);
printf("悔棋b");
goto_xy(1,23);
printf("退出ESC");
constinti=8;//const定义数据不能够被改变而且修改数据比较方便
constintj=19;
constintk=3;
goto_xy(game_xy.x-i,game_xy.y+k);//输出甲方下棋方法
printf("甲方:
●");
goto_xy(game_xy.x-i,game_xy.y+k+2);
printf("移动:
上↑");
goto_xy(game_xy.x-i,game_xy.y+k+4);
printf("下↓");
goto_xy(game_xy.x-i,game_xy.y+k+6);
printf("左←");
goto_xy(game_xy.x-i,game_xy.y+k+8);
printf("右→");
goto_xy(game_xy.x-i,game_xy.y+k+10);
printf("落子:
Enter");
goto_xy(game_xy.x+j,game_xy.y+k);//输出乙方下棋方法
printf("乙方:
○");
goto_xy(game_xy.x+j,game_xy.y+k+2);
printf("移动:
上↑");
goto_xy(game_xy.x+j,game_xy.y+k+4);
printf("下↓");
goto_xy(game_xy.x+j,game_xy.y+k+6);
printf("左←");
goto_xy(game_xy.x+j,game_xy.y+k+8);
printf("右→");
goto_xy(game_xy.x+j,game_xy.y+k+10);
printf("落子:
Enter");
for(intk1=0;k1<200;k1++)//初始化棋子统计,在第二局时有明确作用
for(intk2=0;k2<200;k2++)
Q[k1][k2]=0;
for(inti=0;i<18;i++)//画棋盘
{
if(i==0)//画第一行
{
goto_xy(10,i+3);
printf("┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐");
}
if(i!
=0&&i!
=17)//画出中间16行
{
goto_xy(10,i+3);
printf("├┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┤");
}
if(i==17)//画最终一行
{
goto_xy(10,i+3);
printf("└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘");
}
}
point.x=19;
point.y=12;
goto_xy(19,12);
}
voidClean()//清除—→运动轨迹
{
goto_xy(10,3);
printf("");
goto_xy(24,3);
printf("");
goto_xy(10,4);
printf("");
goto_xy(24,4);
printf("");
}
voidmenu_choose(charpress)//选择游戏还是退出
{
if(press==72)//↑ASCLL码
{
if(point.y==3)
point.y=4;
else
point.y=3;
Clean();
goto_xy(10,point.y);
printf("—→");
}
if(press==80)//↓ASCLL码
{
if(point.y==4)
point.y=3;
else
point.y=4;
Clean();
goto_xy(10,point.y);
printf("—→");
}
if(press==13)//13:
回车键ASCLL码
{
startchoice=point.y-2;//startchoice为1或2
}
}
voidgo_back(intx1,inty1)//悔棋函数
{
goto_xy(x1,y1);
if(x1==10)
{
if(y1==3)
{
printf("┌");
}
elseif(y1==20)
{
printf("└");
}
else
{
printf("├");
}
}
elseif(x1==27)
{
if(y1==3)
{
printf("┐");
}
elseif(y1==20)
{
printf("┘");
}
else
{
printf("┤");
}
}
else
{
if(y1==3)
{
printf("┬");
}
elseif(y1==20)
{
printf("┴");
}
else
{
printf("┼");
}
}
Q[point.x][point.y]=0;//在数组中将弹出棋子对应数据设为0
goto_xy(x1,y1);
}
voidRecord()//统计棋子情况
{
p->coord.x=point.x;
p->coord.y=point.y;
ptr=p;
p=(structPiece*)malloc(sizeof(structPiece));
p->fore=ptr;
ShowWho();
Q[point.x][point.y]=player+1;
if(player)
{
player=0;
return;
}
player=1;
goto_xy(point.x,point.y);
}
voidPutDown()//显示落子函数
{
if(Q[point.x][point.y]==0)//先判定该位置是否有棋子
{
if(player)
{
printf("●");
printf("\a");//'\a'表示蜂鸣声
Record();
}
else
{
printf("○");
printf("\a");
Record();
}
goto_xy(point.x,point.y);
}
}
voidPlay(charch)//键盘操作移动光标下棋和悔棋操作
{
if(ch==72)//↑ASCLL码光标上移
{
if(point.y<=3)
point.y=20;
else
point.y--;
goto_xy(point.x,point.y);
}
if(ch==75)//←ASCLL码光标左移
{
if(point.x<=10)
point.x=27;
else
point.x--;
goto_xy(point.x,point.y);
}
if(ch==77)//→ASCLL码光标右移
{
if(point.x>=27)
point.x=10;
else
point.x++;
goto_xy(point.x,point.y);
}
if(ch==80)//↓ASCLL码光标下移
{
if(point.y>=20)
point.y=3;
else
point.y++;
goto_xy(point.x,point.y);
}
if(ch==13)//回车键ASCLL码下棋
{
PutDown();
}
if(button=='b'||button=='B')//悔棋操作
{
ptr1=p;
if(p!
=head)
{
p=p->fore;
free(ptr1);
point.x=p->coord.x;
point.y=p->coord.y;
go_back(point.x,point.y);
}
}
}
intJudge()
{
intcount=0;
intpp=player==0?
2:
1;//三目运算
for(intc=0;c<200;c++)
{
for(intr=0;r<200;r++)
{
if(Q[r][c]!
=pp)
continue;
//检验列
intrr=r;
intcc=c;
while(--cc>=3&&Q[rr][cc]==pp)
count++;
cc=c;
while(++cc<23&&Q[rr][cc]==pp)
count++;
cc=c;
if(count>=4)
returnpp;
//检验行
count=0;
while(--rr>=10&&Q[rr][cc]==pp)
count++;
rr=r;
while(++rr<30&&Q[rr][cc]==pp)
count++;
rr=r;
if(count>=4)
returnpp;
//检验反斜边
count=0;
cc--;
rr--;
while((cc>=3||rr>=10)&&Q[rr][cc]==pp)
{
count++;
cc--;
rr--;
}
rr=r;
cc=c;
cc++;
rr++;
while((cc<23||rr<30)&&Q[rr][cc]==pp)
{
count++;
cc++;
rr++;
}
rr=r;
cc=c;
if(count+1>=5)
returnpp;
//检验正斜边
count=0;
cc++;
rr--;
while((cc<23||rr>=10)&&Q[rr][cc]==pp)
{
count++;
cc++;
rr--;
}
rr=r;
cc=c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 图形 五子棋 课程设计 报告