五子棋课程设计实验报告.docx
- 文档编号:11091785
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:36
- 大小:210.45KB
五子棋课程设计实验报告.docx
《五子棋课程设计实验报告.docx》由会员分享,可在线阅读,更多相关《五子棋课程设计实验报告.docx(36页珍藏版)》请在冰点文库上搜索。
五子棋课程设计实验报告
C语言程序设计报告
题目:
五子棋
班级:
电气Q1041班
人数:
3人
小组成员:
周啸天、万广富、黄山奇
指导老师:
桂超
时间:
2011.11.30
目录
第一章课程设计的目的和要求3
1.1课程设计的目的3
1.2课程设计的要求3
1.3课程设计的实验环境3
第二章功能描述4
第三章总体设计5
3.1功能模块设计5
3.1.1任务执行流程图5
3.1.2下棋函数流程图6
3.2数据结构设计7
3.2.1定义结构体7
3.2.2定义数组7
3.2.3全局变量7
3.3函数功能描述7
第四章程序实现8
4.1源码分析8
4.2运行结果及界面介绍22
第五章后记27
第一章课程设计的目的和要求
1.1课程设计的目的
1.加深对C语言数据类型,运算,语句结构及其程序设计的基本方法理解和掌握;
2.熟练掌握流程图的绘制、程序设计文档的书写;
3.通过编写一个完整的程序,一方面可以检查我们这学期的学习情况,为以后的学习打下坚实的基础;
4.熟悉C语言游戏编程,掌握五子棋游戏开发的基本原理,从而为以后的程序开发奠定基础。
1.2课程设计的要求
1、编写程序代码,调试所写程序使其能够正确运行;
2、能进行基本的五子棋操作,有图形界面,能够用键盘操作;
3、能够实现悔棋、存档和读档等附加功能
1.3课程设计的实验环境
该课程设计在设计与实验过程中需要在windowsXP系统/windows2000以上系统中进行,程序设计要求在visualC++6.0平台中进行,完成代码的编写、编译、调试、测试等工作。
本游戏对计算机硬件和操作系统要求极低,所以在这里只是把自己的电脑硬件参数和系统参数列下:
硬件:
Cpu:
2.1GHZ,内存,2GB,硬盘:
320GB,操作系统:
windowsxp
软件环境:
安装VC++6.0
第二章功能描述
本程序用C语言实现了五子棋游戏,能进行基本的五子棋操作。
程序能实现界面的初始化功能、下棋功能、人机智能对战功能、胜负判断功能、悔棋功能、读档及存档功能,通过键盘操作控制下棋。
(1)显示欢迎界面。
在游戏开始时出现一个欢迎的界面同时介绍了游戏的规则;
(2)初始化功能。
程序初始化屏幕和棋盘,默认玩家先行。
(3)下棋操作。
利用W、S、A、D及空格键实现下棋操作,在下棋过程中能随时按ESC键退出。
(4)人机智能对战功能。
电脑根据玩家的下棋对棋盘进行智能分析,然后下棋,实现人机对弈。
(5)悔棋功能。
玩家可以有三次悔棋机会。
(6)胜负判断功能。
程序能对下棋的结果进行判断,分出胜负。
并显示获胜方。
(7)读档、存档功能。
游戏中途退出会提示是否存档,如果存档,则下次开始的时候会提示是否读档继续上次的游戏。
第三章总体设计
3.1功能模块设计
3.1.1任务执行流程图
否是
否
是
3.1.2下棋函数流程图
是否
否
是
否是
否
否
是
3.2数据结构设计
3.2.1定义结构体
将棋盘上每个点的左边定义为一个结构体;
typedefstruct
{
intx,y;
}point;
3.2.2定义数组
定义数组board[15][15]表示棋盘,用来记录棋盘上每个棋子的状态;
3.2.3全局变量
定义整形数组back[4]用来记录前两步双方下棋的状态,便于后面进行悔棋操作
定义整形n=3;用来记录悔棋次数
3.3函数功能描述
1、显示欢迎信息boolwelcome();
2、初始化棋盘voidInitBoard();
3、输出棋盘voidchessboard();
4、判断胜负intWin(charc);
5、下棋voidplay(point&r);
6、显示获胜voidshowsusscced(charc);
7、悔棋boolBackStep(intback[]);
8、人机对战智能算法voidComAlgo(point&r);
9、存盘函数boolSaveLoad();
10、读盘函数boolDownLoad();
第四章程序实现
4.1源码分析
1、显示欢迎信息
boolwelcome()
{
charch;
printf("\n\n\n\n");
printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("┃WelcomeyoutogobangWorld!
┃\n");
printf("┃1、YoucanusetheA,D,WandSkeytomovethechessman;┃\n");
printf("┃2、YoucanpressSpacekeytoenterafteryoumoveit;┃\n");
printf("┃3、YoucanuseEsckeytoexitthegame;┃\n");
printf("┃4、Don'tmovethepiecesoutofthechessboard.┃\n");
printf("┃Doyouwanttocontinue?
(Y/N)┃\n");
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
while(!
strchr("YN",ch=toupper(getch())))
{
putchar('\a');
}
if(ch=='N')returnfalse;
elsereturntrue;
}
2、初始化棋盘
voidInitBoard()
{
charch;inti,j;
printf("\n\n是否读档?
(Y/N)\n");
if((ch=toupper(getch()))=='Y'&&DownLoad())
printf("读档成功!
\n");
else
{
for(i=0;i<15;i++)
for(j=0;j<15;j++)
board[i][j]='';
}
chessboard();
}
3、输出棋盘
voidchessboard()
{
//清屏
system("cls");
//输出棋盘的上边缘
printf("010203040506070809101112131415\n");
printf("┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓\n");
printf("┃│││││││││││││││┃\n");
for(inti=1;i<=15;i++)
{
//输出列序号及相应的列元素
printf("%02d┣─",i);
for(intj=1;j<=15;j++)
{
switch(board[i-1][j-1])
{
//(由于在命令行模式下显示,所以,颜色是颠倒的)
case'':
printf("┼─");break;//如果当前位置无子,则输出棋盘
case'h':
printf("○─");break;//如果是黑子,则输出黑子的符号
case'b':
printf("●─");break;//如果是白子,则输出白子的符号
case'g':
printf("⊙─");break;//显示光标
}
}
//输出每列的最后一个制表符
printf("┫%02d\n",i);
printf("┃│││││││││││││││┃\n");
}
printf("┗━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┛\n");
printf("010203040506070809101112131415\n");
}
4、下棋
voidplay(point&r)
{
charkey,c;
do
{
while(!
strchr("ADWSZ",key=toupper(getch())))
{
if(key==27||key==32)break;
putchar('\a');
}
switch(key)
{
case'A':
//向左
if(r.y<=1)break;
elser.y--;
c=board[r.x-1][r.y-1];//记录光标
board[r.x-1][r.y-1]='g';
chessboard();
board[r.x-1][r.y-1]=c;
break;
case'D':
//向右
if(r.y>=15)break;
elser.y++;
c=board[r.x-1][r.y-1];
board[r.x-1][r.y-1]='g';
chessboard();
board[r.x-1][r.y-1]=c;
break;
case'W':
//向上
if(r.x<=1)break;
elser.x--;
c=board[r.x-1][r.y-1];
board[r.x-1][r.y-1]='g';
chessboard();
board[r.x-1][r.y-1]=c;
break;
case'S':
//向下
if(r.x>=15)break;
elser.x++;
c=board[r.x-1][r.y-1];
board[r.x-1][r.y-1]='g';
chessboard();
board[r.x-1][r.y-1]=c;
break;
case32:
//SPACE空格
if(board[r.x-1][r.y-1]!
='')key=0;//key的值修改为非32的数值
else
{
board[r.x-1][r.y-1]='b';
back[0]=r.x-1;back[1]=r.y-1;//记录当前位置,便于悔棋
chessboard();
}
break;
case'Z':
//悔棋
BackStep(back);
break;
case27:
//ESC退出
printf("GameOver!
\n");
printf("是否存档?
(Y/N)\n");
if((c=toupper(getch()))=='Y'&&SaveLoad())
printf("存档成功!
\n");
exit
(1);
default:
fflush(stdin);
}
}while(key!
=32);
}
注:
1、W、S、A、D分别表示上下左右键。
如果超出了棋盘则不进行操作。
否则向键值指示的方向移动一步。
2、c=board[r.x-1][r.y-1];
board[r.x-1][r.y-1]='g';
chessboard();
board[r.x-1][r.y-1]=c;
这四句表示记录当前移动位置,然后显示光标,显示完以后还原棋盘。
3、按空格键表示下棋,如果当前位置有棋子则不进行操作。
back[0]=r.x-1;back[1]=r.y-1;用于记录当前位置,便于悔棋。
4、按Z悔棋
5、按ESC键退出,并且提示是否存档。
5、判断胜负
intWin(charc)
{
inti,j,ok=1;
//判断横着的5个是否都相等
for(i=0;i<15;i++)
{
for(j=0;j<11;j++)
if(board[i][j]==c&&board[i][j+1]==c&&board[i][j+2]==c&&board[i][j+3]==c&&board[i][j+4]==c)
returnok;
}
//判断竖着的5个是否都相等
for(j=0;j<15;j++)
{
for(i=0;i<11;i++)
if(board[i][j]==c&&board[i+1][j]==c&&board[i+2][j]==c&&board[i+3][j]==c&&board[i+4][j]==c)
return1;
}
//判断左斜5个是否都相等
for(i=0;i<11;i++)
{
for(j=0;j<11;j++)
if(board[i][j]==c&&board[i+1][j+1]==c&&board[i+2][j+2]==c&&board[i+3][j+3]==c&&board[i+4][j+4]==c)
returnok;
}
//判断右斜5个是否都相等
for(i=0;i<11;i++)
{
for(j=14;j>3;j--)
if(board[i][j]==c&&board[i+1][j-1]==c&&board[i+2][j-2]==c&&board[i+3][j-3]==c&&board[i+4][j-4]==c)
returnok;
}
returnok=0;
}
注:
全篇扫面棋盘,从四个方向判断是否存在连着5个棋子
6、显示获胜
voidshowsusscced(charc)
{
if(c=='b')
{
printf("游戏结束白棋获胜!
\n");
}
elseif(c=='h')
{
printf("游戏结束黑棋获胜!
\n");
}
else
{
printf("游戏结束和棋!
\n");
}
}
7、悔棋
boolBackStep(intback[])
{
if(n>0)
{
board[back[0]][back[1]]=board[back[2]][back[3]]='';
chessboard();
n--;
printf("悔棋成功,您还有%d次悔棋机会\n",n);
returntrue;
}
else
{
printf("悔棋超过三次,您不能悔棋了!
\n");
returnfalse;
}
}
8、存盘函数
boolSaveLoad()
{
FILE*f;
f=fopen("Load.TXT","w");
if(f==NULL)
{
printf("存档失败!
\n");
returnfalse;
}
else
{
fwrite(board,sizeof(char),225,f);
fclose(f);
returntrue;
}
}
9、读盘函数
boolDownLoad()
{
FILE*f;
f=fopen("Load.TXT","r");
if(f==NULL)
{
printf("读档失败!
\n");
returnfalse;
}
else
{
fread(board,sizeof(char),225,f);
fclose(f);
returntrue;
}
}
注:
存盘存在当前文件夹内的Load.txt文件中,用fwrite()函数和fread()函数读取和存储数组元素。
10、人机对战智能算法
voidComAlgo(point&r)
{
//棋型数组
intqiju[2][15][15][8][2]={0};
/*其中第一个下标为0时表示白棋,为1时表示黑棋,第二和第三个下标表示(x,y),
第四个下标表示8个方向,最后一个下标为0时表示棋子数,为1时表示空格数*/
chard;//表示黑棋或白棋
intk,i,j,q,a=1;//(k,i,j,q,0/1)表示棋型数组;a,b用来计数
intb=0,y1=0,y2=0,x1=0,x2=0;//b表示得分;(x1,y1)和(x2,y2)表示坐标
inta1[15][15]={0},a2[15][15]={0};//用来记录白棋和黑棋各个棋子位置的得分
/****************为双方填写棋型表************/
for(k=0;k<2;k++)
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
if(board[i][j]=='')
{
for(q=0;q<8;q++)
{
if(k==0)d='b';
elsed='h';
//左←
if(q==0&&j>=0)
{
for(;j-a>=0;)
{
if(board[i][j-a]==d){b++;a++;continue;}
elsebreak;
}
qiju[k][i][j][q][0]=b;b=0;
if(board[i][j-a]==''&&j-a>=0){qiju[k][i][j][q][1]=1;a=1;}
else{qiju[k][i][j][q][1]=0;a=1;}
}
//左上↖
if(q==1&&i>=0&&j>=0)
{
for(;i-a>=0&&j-a>=0;)
{
if(board[i-a][j-a]==d){b++;a++;continue;}
elsebreak;
}
qiju[k][i][j][q][0]=b;b=0;
if(board[i-a][j-a]==''&&j-a>=0&&i-a>=0){qiju[k][i][j][q][1]=1;a=1;}
else{qiju[k][i][j][q][1]=0;a=1;}
}
//上↑
if(q==2&&i>=0)
{
for(;i-a>=0;)
{
if(board[i-a][j]==d){b++;a++;continue;}
elsebreak;
}
qiju[k][i][j][q][0]=b;b=0;
if(board[i-a][j]==''&&i-a>=0){qiju[k][i][j][q][1]=1;a=1;}
else{qiju[k][i][j][q][1]=0;a=1;}
}
//右上↗
if(q==3&&i>=0&&j<15)
{
for(;i-a>=0&&j+a<15;)
{
if(board[i-a][j+a]==d){b++;a++;continue;}
elsebreak;
}
qiju[k][i][j][q][0]=b;b=0;
if(board[i-a][j+a]==''&&i-a>=0&&j+a<15){qiju[k][i][j][q][1]=1;a=1;}
else{qiju[k][i][j][q][1]=0;a=1;}
}
//右→
if(q==4&&j<15)
{
for(;j+a<15;)
{
if(board[i][j+a]==d){b++;a++;continue;}
elsebreak;
}
qiju[k][i][j][q][0]=b;b=0;
if(board[i][j+a]==''&&j+a<15){qiju[k][i][j][q][1]=1;a=1;}
else{qiju[k][i][j][q][1]=0;a=1;}
}
//右下↘
if(q==5&&i<15&&j<15)
{
for(;i+a<15&&j+a<15;)
{
if(board[i+a][j+a]==d)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 五子棋 课程设计 实验 报告