c++上机实习报告五子棋Word文档下载推荐.docx
《c++上机实习报告五子棋Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《c++上机实习报告五子棋Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
其次、定义了一个棋盘类。
这个类封装了棋盘的数据存储和落子下棋,刷新
棋盘等功能。
定义好各子模块的接口。
再则、分开实现各个棋盘类的方法操作。
函数的调用,函数的构造等。
再次、使用一些基本控制语句和I/O流来实现各种功能•例如:
IF语
句,IF……ELSE…语句,WHILE循环语句‘SWITCH语句,FOR循环语句等。
最后、通过编译、运行在dos环境下实现实际的结果。
算法的整体思路:
在用户选择开始游戏后,首先需要初始化棋盘类,输出棋盘到dos界面上。
然后,调用下棋模块,与用户交互过程中,每下一步,判断输入是否正确并刷新棋盘。
最后,在每一步后判断胜负。
如果已分出胜负,输出结果并初始化棋盘,否则继续上一步操作。
整体框图
刿斬月生荧
1棋盘类
整个架构的核心部分,如保存棋盘数据、初始化、交互来完成对游戏的操作。
三详细设计
类名为Qipan。
封装了棋盘的各种可能用到的功能⑶,判断胜负等。
用户操作主界面,主界面与Qipan进行
类图
类名;
愆飄
属性;
Inta;
/尼录坐标位置
城匕川记录坐标位逼
Intplayer;
"
用干在(alCb]处落子
Iijtname[闻[N]lF府旅棋盘数据分别甲1、0表亦不同颜色子和空汚法:
intwrnQ;
停」断胜负
voidresetsJ庫貧棋盘
voidche£
stioardOy/~FtMJF®
5绘棋盘
2.绘制棋盘模块
当游戏初始化时,和每当落子消息触发时,都需要对棋盘进行重绘。
这里用特殊符号“O”+”分别来描绘白子、黑子和棋盘空格。
这个函数主要完
成了以下工作:
装载棋盘二位数组并进行绘制。
根据棋盘数据绘制棋子。
绘制最后落子指示矩形。
绘制棋盘’定义变屋打
I电iz
KN
J=0护4
i>
N环
j>
N退出循环
Ves
No
益出P”
判断;
liametij[j
}=C
Yes
齡岀+
判断n
【订【订=1
?
es.
输出9”
输出y
完成描1行’輸出换行符
複盘绘制结审
3.键盘操作控制模块
此模块主要用于处理与用户的交互过程。
即完成落子判断过程此模块主要完成以下工作:
从键盘读入控制信息(上下左右移动和落子)
判断是否在棋盘内安落子键,和移动是否超出棋盘范围判断落子点是否已有棋子
键盘操作控制
从鯉盘输入控制键:
ititinputs呂etchC)
lnpul=TS.T||丫
lnput=JDird,
Inputs俪入键为空客
如杲a>
如果20
如呆buN-j
name[a][b]—0
d'
b-■
d++
YES
NO
控制上移
控制下楼
控制左福
控制右楼
可UA落子若pkyer^l
则贼個为
2
反之亦然
此处有子娶求重新输人
4.判断胜负模块
这是游戏中一个极其重要的算法,用来判断当前棋盘的形势是哪一方获胜。
五子棋的胜负,在于判断棋盘上是否有一个点,从这个点开始的右、下、右下、左下四个方向是否有连续的五个同色棋子出现,如图:
这个算法也就是Qipan的Win成员函数。
从设计的思想上,需要它接受一个棋子颜色的参数,然后返回一个布尔值,这个值来指示是否胜利。
这里用一个数组intcount[8]来控制2中颜色4个方向的棋子情况。
Count[i]中i为单数表示白子个数,其中count[1]=j,表示横方向上白子连续个数为j,cont[3]=j表
示竖方向上,count[5]=j表示从左到右斜方向,count[7]=j表示从右到左斜方向。
双数表示黑子,同白子原理一样。
3.4.1横向判断设计图
定义变童:
血ijM舵制循环变量血wuntgO};
循环控制丘1司屮
I<
N
循环控制%£
=i]?
k++
K<
5
M5
Name[i][j+-k]=l
Name[i]J+k]=2
Comt[l]++
爺出结見win=outpLit(ct)
342竖向判断设计图“|”
说明:
由于外循环(即i,j控制的棋盘循环)各方向上的判断是一致的下面其它方向的判断就不在赘述。
下面所给出的都是有变化的内循环控制。
竖向判断设计图
循坏控制久K=O;
k>
=5
Name[i+k]^]=l
Name[计
Couiit[2]++
■III■■1
Count(3]++
3.4.3从左到右斜方向
循环控制5:
K-O?
Name[i-hk][j+k]=l
Name[i-bk]]j+k]=2
Comt[4]++
Count[5]++
344从右到左斜方向“/
循环控制5;
K=O;
Name[i+k][j-k]=l
Name[i+k][j-k]=2
Couni[6]++
Count[7]++
4.重置棋盘模块
在每一局游戏开始的时候都需要调用这个函数reset()将棋盘清空,也就是
棋盘的初始化工作。
在这个函数中,主要发生了这么几件事情:
将name[N][N]中每一个落子位都置为无子状态(0)。
将光标的初始位置,置于棋盘正中即a=N/2,b=N/2
默认的先手顺序是黑子先手,置player=1
5.游戏说明模块
这一模块主要是介绍此程序的操作方法。
只是简单的用一系列cout语句输出说明文字。
这里不再详细介绍。
6.游戏结束模块
这一模块主要用于释放内存,用输出流语句输出结束信息,并控制循环退出程序。
四程序的调试与运行结果说明
1.进入游戏->
主界面
ISEitaVHLhesssfivfcscfiesss_cixr^iDfc?
bLjij,*
2.点击1->
开始游戏
3.继续点击1或2->游戏过程中
4.判断胜负
5.
在主界面中点击2->游戏说明
6.在主界面中点击0->退出游戏
B"
C:
\DooimEntsandSettin^s\Administrator\S=面\
五课程设计总结
此次课程设计的作品基本达到了要求,完成了五子棋游戏的软件,提供了五子棋游戏的基本下棋控制,胜负判断。
但仍然是一个粗糙的学生作品而已,有待进步完善。
我对此软件的进一步设想是:
可以增加玩家信息排行功能,记录玩家姓名、获胜率等信息,有助于提高游戏的挑战性。
还可以添加悔棋功能。
满足用户更多的需求。
通过进一步的C++学习,把dos界面的五子棋游戏改编成更美观好用的windows界面。
通过进一步学习人工智能等知识,完善程序,使之能实现人机对战。
最后是学习网络知识,希望能使此程序能实现在网上了双人对战。
并附加聊天功能和他人观战功能等。
六后记
通过编写这个程序,我体会最为深刻的一点是系统架构和设计模式的重要性。
即使是对于一个并不大的程序,代码的组织都是非常重要的,因为这关系到日后的维护以及扩展。
这个游戏之中,有关各种算法思想的设计在网络上都能找到。
但是对于系统的架构,却完全是自己的事情,成百上千的代码需要通过合适的方法组织起来,使程序员编写代码更加有条理,更加符合软件工程的标准,这才是最重要的。
在刚开始编写这个程序的时候,我幼稚地认为其中最重要的是算法设计。
但是头两天编写程序的时候却发现程序越写越不容易维护,可见是我走错了方向。
但是对于代码的组织(也就是软件的架构)才是真正软件工业的核心部分,因为软件事实上是直接和经济挂钩的,因此我们必须在编写代码之前选择一种最为合适的方法来组织这些代码,否则我们将会失去更多的时间和金钱。
于是,我将以前写的代码全部删除,认真地思考了一段时间。
我也在这三天内真正从一个学生走入了软件开发的大门,我开始发现其实软件开发并不是纯数学一一正相反,数学只占了很小的一部分。
它其实是一种哲学,一种有着数学美感的哲学。
在这此课程设计中还遇到一个比较重大的问题。
我一开始是打算写一个windows界面的五子棋游戏,于是前两天时间一直在一边学习vc可视化编程,
一边构建界面。
在短时间了看了很多本书,但还是由于时间的关系和对API函数的不熟悉,使我最后放弃了windows界面的设计思想。
虽然最后没做出想要的结果,但是在这次课程设计中我真的学到了不少东西。
相信我一定能在进一步学习后拿出更好的作品以弥补此次的遗憾。
参考文献
[1]甘玲石岩李盘林,解析C++面向对象程序设计,北京,清华大学出版社,2000年9
月。
[2]黄维通,VisualC++面向对象与可视化程序设计,北京,清华大学出版社,2003年2月
[3]张基温张伟,C++程序开发例题与习题,北京,清华大学出版社,2003年7月
[4]严蔚敏,数据结构(C语言版),北京,清华大学出版社,1996年
附录一一源代码
〃++++++fivechess_qxf..h开始+++++++++++
#include<
stdio.h>
#include<
stdlib.h>
#include<
conio.h>
iostream>
usingnamespacestd;
#defineN21
intoutput(intcount[8],intwin);
//输入胜负
voidexplain();
〃游戏说明
classQipan
{
public:
inta;
intb;
intplayer;
//用于在【a】【b】处落子
intname[N][N];
//存放棋盘数据
intwin();
//判断胜负
voidreset();
//重置棋盘
voidchessboard。
;
//下棋并描绘棋盘
};
〃+++++++++fivechess_qxf.h//====main.cpp开始
#include"
fivechess_qxf.h"
voidmain()
Qipanqipan;
intt,j,i;
qipan.a=N/2;
qipan.b=N/2;
system("
cls"
);
结束+++++++++
for(i=0;
i<
=N;
i++)
for(j=0;
j<
j++)
{qipan.name[i][j]=0;
}
do
cout<
<
1.开始游戏"
endl;
2.游戏说明"
0.结束游戏"
scanf("
%d"
&
t);
switch(t)
case1:
'
end
l;
1.先手白棋"
2.先手黑棋"
l;
scanf("
qipan.player);
do
qipan.chessboard。
;
}while(qipan.win());
qipan.reset();
break;
case2:
explain();
case0:
谢谢使用!
fflush(stdin);
j=getch();
}while(t);
//=====main.cpp结束=//====reset.cpp开始=
//重置棋盘
voidQipan:
:
reset()
inti,j;
for(i=0;
N;
{name[i][j]=0;
}
a=N/2;
b=N/2;
player=1;
//===reser.cpp结束=〃====explain.cpp开始=
usingnamespacestd;
//游戏说明
//====chessboard.cpp开始=
//
//刷新棋盘落子下棋
voidexplain()
chessboard()
intj;
****************************
游戏说明{
******************************"
en
dl;
1.按w向上移动光标"
2.按s向下移动光标"
3.按a向左移动光标"
if(a==i&
&
b==j)
□"
4.按d向右移动光标"
5.按空格放子"
elseif(name[i][j]==0)
********************
endl;
按任意键回到主菜单"
+"
//=====explain.cpp结束=
elseif(name[i][j]==1)
•"
else
O"
case'
a'
if(b>
0)
b--;
intinput=getch();
switch(input)
if(b<
N-1)
w'
if(a>
b++;
a--;
if(name[a][b]==0)
s'
if(a<
player=player==1?
2:
1;
name[a][b]=player;
a++;
}else
for(k=0;
k<
5;
k++)
if(name[i][j+k]==1)
此处有子!
"
按任意键继续"
//====chessboard.cpp结束=
//====win.cpp开始=======
intQipan:
win()
inti,j,count[8]={0},k,win;
//判断从左到右是否5个
count[O]++;
if(name[i][j+k]==2)
count[1]++;
win=output(count,win);
//判断列是否5个
if(name[i+k][j]==1)
count[2]++;
if(name[i+k][j]==2)
count[3]++;
//判断左到右斜方向是否有5个
if(name[i+k][j+k]==1)
count[4]++;
if(name[i+k][j+k]==2)
count[5]++;
//判断右到左斜方向是否有5个
for(j=1;
if(name[i+k][j-k]==1)
count[6]++;
if(name[i+k][j-k]==2)
count[7]++;
II
returnwin;
//输出胜负
intoutput(intcount[8],intwin)
if(count[0]==5||count[2]==5||
count[4]==5||count[6]==5)
win=0;
白子赢了"
if(count[1]==5||count[3]==5
count[5]==5||count[7]==5)
黑子赢了"
8;
{count[i]=0;
//======win.cpp结束======