ugtllt五子棋毕业论文设计.docx
- 文档编号:25379072
- 上传时间:2023-06-07
- 格式:DOCX
- 页数:23
- 大小:26.55KB
ugtllt五子棋毕业论文设计.docx
《ugtllt五子棋毕业论文设计.docx》由会员分享,可在线阅读,更多相关《ugtllt五子棋毕业论文设计.docx(23页珍藏版)》请在冰豆网上搜索。
ugtllt五子棋毕业论文设计
优秀论文审核通过
未经允许切勿外传
五子棋设计
【摘要】本论文主要阐述以面向对象的程序开发语言VC++为开发工具,设计一个五子棋游戏。
本系统是个小型游戏,可以单机使用,也可以网络两个人游戏,也可以和电脑进行游戏。
论文首先介绍了开发背景及开发语言的介绍。
然后介绍设计该游戏的框架结构,然后介绍了程序的设计过程,以及程序的相关算法。
关键词:
游戏,系统,图片,VISUALC++
目录
1 引言1
1.1 五子棋介绍1
1.2 开发背景1
1.3 开发环境及运行环境1
1.3.1 开发环境1
1.3.2 运行环境1
2 软件架构2
2.1 棋盘类2
2.2 游戏模式类3
3 棋盘类——CTable4
3.1 主要成员变量说明4
3.1.1 网络连接标志4
3.1.2 棋盘等待标志4
3.1.3 网络套接字4
3.1.4 棋盘数据4
3.1.5 游戏模式指针5
3.2 主要成员函数说明5
3.2.1 套接字的回调处理5
3.2.2 清空棋盘5
3.2.3 绘制棋子5
3.2.4 左键消息6
3.2.5 绘制棋盘6
3.2.6 对方落子完毕6
3.2.7 设置游戏模式6
3.2.8 胜负的判断7
4 游戏模式类8
4.1 主要成员变量说明9
4.1.1 棋盘指针9
4.1.2 落子步骤9
4.2 主要成员函数说明9
4.2.1 悔棋操作9
4.2.2 初始化操作9
4.2.3 接收来自对方的消息10
4.2.4 发送落子消息10
4.2.5 胜利后的处理10
5 消息机制11
5.1 消息机制的架构11
5.2 各种消息说明11
5.2.1 落子消息12
5.2.2 悔棋消息12
5.2.3 同意悔棋消息13
5.2.4 拒绝悔棋消息13
5.2.5 和棋消息13
5.2.6 同意和棋消息13
5.2.7 拒绝和棋消息14
5.2.8 认输消息14
5.2.9 聊天消息14
5.2.10 对方信息消息15
5.2.11 再次开局消息15
5.2.12 同意再次开局消息15
6 主要算法16
6.1 判断胜负16
6.2 人机对弈算法18
6.2.1 获胜组合19
6.2.2 落子后处理19
6.2.5 防守策略23
6.2.6 选取最佳落子24
7 几点补充说明25
8 心得体会26
参考文献27
致谢28
1 引言
1.1 五子棋介绍
五子棋是起源于中国古代的传统黑白棋种之一。
现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(FiveinaRow的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。
它是中西文化的交流点,是古今哲理的结晶。
1.2 开发背景
当前网络上流传的五子棋游戏功能并不尽善尽美,其中最主要的问题就是人机对战和网络对战不能够一起实现,所以我决定开发[1]一个既能够人机对战,又能够进行网络对战的五子棋系统。
1.3 开发环境及运行环境
1.3.1 开发环境
●Intel®Pentium®42.0GHz,512M内存,80G硬盘
●Microsoft®Windows™2000Professional
●Microsoft®VisualC++6.0
●Microsoft®DeveloperNetworkforVisualStudio.NET2003
●VisualAssistX10.1.1301.0
1.3.2 运行环境
●Intel®Pentium®2及以上处理器,32M以上内存,4G以上硬盘
●Microsoft®Windows™9XNT操作系统
●800*600或以上的屏幕分辨率
2 软件架构
软件的总体架构如图2.1:
图2.1软件架构
考虑到整个的下棋过程(无论对方是电脑抑或其他网络玩家)可以分为:
己方落子、等待对方落子、对方落子、设置己方棋盘数据这一系列过程,因此一人游戏类、二人游戏类和棋盘类之间的关系参考了AbstractFactory(抽象工厂)模式,以实现对两个不同模块进行一般化的控制。
[2]
2.1 棋盘类
整个架构的核心部分,类名为CTable。
封装了棋盘的各种可能用到的功能[3],如保存棋盘数据、初始化、判断胜负等。
用户操作主界面,主界面与CTable进行交互来完成对游戏的操作。
2.2 游戏模式类
用来管理人机对弈网络对弈两种游戏模式,类名为CGame。
CGame是一个抽象类,经由它派生出一人游戏类COneGame和网络游戏类CTwoGame,如图2.2:
图2.2CGame类派生关系
这样,CTable类就可以通过一个CGame类的指针[4],在游戏初始化的时候根据具体游戏模式的要求实例化COneGame或CTwoGame类的对象;然后利用多态性[5],使用CGame类提供的公有接口就可以完成不同游戏模式下的不同功能了。
3 棋盘类——CTable
3.1 主要成员变量说明
3.1.1 网络连接标志——m_bConnected
用来表示当前网络连接的情况,在网络对弈游戏模式下客户端连接服务器的时候用来判断是否连接成功;事实上,它也是区分当前游戏模式的唯一标志。
3.1.2 棋盘等待标志——m_bWait与m_bOldWait
由于在玩家落子后需要等待对方落子,m_bWait标志就用来标识棋盘的等待状态。
当m_bWait为TRUE时,是不允许玩家落子的。
在网络对弈模式下,玩家之间需要互相发送诸如悔棋、和棋这一类的请求消息,在发送请求后等待对方回应时,也是不允许落子的,所以需要将m_bWait标志置为TRUE。
在收到对方回应后,需要恢复原有的棋盘等待状态,所以需要另外一个变量在发送请求之前保存棋盘的等待状态做恢复之用,也就是m_bOldWait。
等待标志的设置,由成员函数SetWait和RestoreWait完成。
3.1.3 网络套接字——m_sock和m_conn
在网络对弈游戏模式下,需要用到这两个套接字对象。
其中m_sock对象用于做服务器时的监听之用,m_conn用于网络连接的传输。
3.1.4 棋盘数据——m_data
这是一个15*15的二位数组,用来保存当前棋盘的落子数据。
其中对于每个成员来说,0表示落黑子,1表示落白子,-1表示无子。
3.1.5 游戏模式指针——m_pGame
这个CGame类的对象指针是CTable类的核心内容。
它所指向的对象实体决定了CTable在执行一件事情时候的不同行为,具体的内容请参见“游戏模式”一节。
3.2 主要成员函数说明
3.2.1 套接字的回调处理——Accept、Connect、Receive
本程序的套接字派生自MFC的CAsyncSocket类[6],CTable的这三个成员函数就分别提供了对套接字[7]回调事件OnAccept、OnConnect、OnReceive的实际处理,其中尤以Receive成员函数重要,它之中包含了对所有网络消息(参见“消息机制”一节)的分发处理。
3.2.2 清空棋盘——Clear
在每一局游戏开始的时候都需要调用这个函数将棋盘清空,也就是棋盘的初始化工作。
在这个函数中,主要发生了这么几件事情:
●将m_data中每一个落子位都置为无子状态(-1)。
●按照传入的参数设置棋盘等待标志m_bWait,以供先、后手的不同情况之用。
●使用delete将m_pGame指针所指向的原有游戏模式对象从堆上删除。
3.2.3 绘制棋子——Draw
这无疑是很重要的一个函数,它根据参数给定的坐标和颜色绘制棋子。
绘制的详细过程如下:
●将给定的棋盘坐标换算为绘图的像素坐标。
●根据坐标绘制棋子位图。
●如果先前曾下过棋子,则利用R2_NOTXORPEN将上一个绘制棋子上的最后落子指示矩形擦除。
●在刚绘制完成的棋子四周绘制最后落子指示矩形。
3.2.4 左键消息——OnLButtonUp
作为棋盘唯一响应的左键消息,也需要做不少的工作:
●如果棋盘等待标志m_bWait为TRUE,则直接发出警告声音并返回,即禁止落子。
●如果点击时的鼠标坐标在合法坐标(0,0)~(14,14)之外,亦禁止落子。
●如果走的步数大于1步,方才允许悔棋。
●进行胜利判断,如胜利则修改UI状态并增加胜利数的统计。
●如未胜利,则向对方发送已经落子的消息。
●落子完毕,将m_bWait标志置为TRUE,开始等待对方回应。
3.2.5 绘制棋盘——OnPaint
每当WM_PAINT消息触发时,都需要对棋盘进行重绘。
OnPaint作为响应绘制消息的消息处理函数使用了双缓冲技术,减少了多次绘图可能导致的图像闪烁问题。
这个函数主要完成了以下工作:
●装载棋盘位图并进行绘制。
●根据棋盘数据绘制棋子。
●绘制最后落子指示矩形。
3.2.6 对方落子完毕——Over
在对方落子之后,仍然需要做一些判断工作,这些工作与OnLButtonUp中的类似,在此不再赘述。
3.2.7 设置游戏模式——SetGameMode
这个函数通过传入的游戏模式参数对m_pGame指针进行了初始化,代码如下:
voidCTable:
:
SetGameMode(intnGameMode)
{
if(1==nGameMode)
m_pGame=newCOneGame(this);
else
m_pGame=newCTwoGame(this);
m_pGame->Init();
}
这之后,就可以利用OO的继承和多态特点[8]来使m_pGame指针使用相同的调用来完成不同的工作了,事实上,COneGame:
:
Init和CTwoGame:
:
Init都是不同的。
3.2.8 胜负的判断——Win
这是游戏中一个极其重要的算法,用来判断当前棋盘的形势是哪一方获胜。
其详细内容请参见“主要算法”一节。
4 游戏模式类——CGame
这个类负责对游戏模式进行管理,以及在不同的游戏模式下对不同的用户行为进行不同的响应。
由于并不需要CGame本身进行响应,所以将其设计为了一个纯虚类[9],它的定义如下:
classCGame
{
protected:
CTable*m_pTable;
public:
落子步骤
list
public:
构造函数
CGame(CTable*pTable):
m_pTable(pTable){}
析构函数
virtual~CGame();
初始化工作,不同的游戏方式初始化也不一样
virtualvoidInit()=0;
处理胜利后的情况,CTwoGame需要改写此函数完成善后工作
virtualvoidWin(constSTEP&stepSend);
发送己方落子
virtualvoidSendStep(constSTEP&stepSend)=0;
接收对方消息
virtualvoidReceiveMsg(MSGSTRUCT*pMsg)=0;
发送悔棋请求
virtualvoidBack()=0;
};
4.1 主要成员变量说明
4.1.1 棋盘指针——m_pTable
由于在游戏中需要对棋盘以及棋盘的父窗口——主对话框进行操作及UI状态设置,故为CGame类设置了这个成员。
当对主对话框进行操作时,可以使用m_pTable->GetParent()得到它的窗口指针。
4.1.2 落子步骤——m_StepList
一个好的棋类程序必须要考虑到的功能就是它的悔棋功能,所以需要为游戏类设置一个落子步骤的列表。
由于人机对弈和网络对弈中都需要这个功能,故将这个成员直接设置到基类CGame中。
另外,考虑到使用的简便性,这个成员使用了C++标准模板库[10](StandardTemplateLibrary,STL)中的std:
:
list,而不是MFC的CList。
4.2 主要成员函数说明
4.2.1 悔棋操作——Back
在不同的游戏模式下,悔棋的行为是不一样的。
●人机对弈模式下,计算机是完全允许玩家悔棋的,但是出于对程序负荷的考虑(此原因请参见“几点补充说明”一节),只允许玩家悔当前的两步棋(计算机一步,玩家一步)。
●双人网络对弈模式下,悔棋的过程为:
首先由玩家向对方发送悔棋请求(悔棋消息),然后由对方决定是否允许玩家悔棋,在玩家得到对方的响应消息(允许或者拒绝)之后,才进行悔棋与否的操作。
4.2.2 初始化操作——Init
对于不同的游戏模式而言,也就有不同的初始化方式。
对于人机对弈模式而言,初始化操作包括以下几个步骤:
●设置网络连接状态m_bConnected为FALSE。
●设置主界面计算机玩家的姓名。
●初始化所有的获胜组合。
●如果是计算机先走,则占据天元(棋盘正中央)的位置。
网络对弈的初始化工作暂为空,以供以后扩展之用。
4.2.3 接收来自对方的消息——ReceiveMsg
这个成员函数由CTable棋盘类的Receive成员函数调用,用于接收来自对方的消息。
对于人机对弈游戏模式来说,所能接收到的就仅仅是本地模拟的落子消息MSG_PUTSTEP;对于网络对弈游戏模式来说,这个成员函数则负责从套接字读取对方发过来的数据,然后将这些数据解释为自定义的消息结构,并回到CTable:
:
Receive来进行处理。
4.2.4 发送落子消息——SendStep
在玩家落子结束后,要向对方发送自己落子的消息。
对于不同的游戏模式,发送的目标也不同:
●对于人机对弈游戏模式,将直接把落子的信息(坐标、颜色)发送给COneGame类相应的计算函数。
●对于网络对弈游戏模式,将把落子消息发送给套接字,并由套接字转发给对方。
4.2.5 胜利后的处理——Win
这个成员函数主要针对CTwoGame网络对弈模式。
在玩家赢得棋局后,这个函数仍然会调用SendStep将玩家所下的制胜落子步骤发送给对方玩家,然后对方的游戏端经由CTable:
:
Win来判定自己失败。
5 消息机制
Windows系统拥有自己的消息机制,在不同事件发生的时候,系统也可以提供不同的响应方式[11]。
五子棋程序也模仿Windows系统实现了自己的消息机制,主要为网络对弈服务,以响应多种多样的网络消息。
5.1 消息机制的架构
当继承自CAsyncSocket的套接字类CFiveSocket收到消息时,会触发CFiveSocket:
:
OnReceive事件[12],在这个事件中调用CTable:
:
Receive,CTable:
:
Receive开始按照自定义的消息格式接收套接字发送的数据,并对不同的消息类型进行分发处理。
图5.1自定义的消息机制
如图5.1所示,当CTable获得了来自网络的消息之后,就可以使用一个switch结构来进行消息的分发了。
5.2 各种消息说明
网络间传递的消息,都遵循以下一个结构体的形式:
摘自Messages.(intcolor)const
{
intx,y;
判断横向
for(y=0;y<15;y++)
{
for(x=0;x<11;x++)
{
if(color==m_data[x][y]&&
color==m_data[x+1][y]&&
color==m_data[x+2][y]&&
color==m_data[x+3][y]&&
color==m_data[x+4][y])
{
returnTRUE;
}
}
}
判断纵向
for(y=0;y<11;y++)
{
for(x=0;x<15;x++)
{
if(color==m_data[x][y]&&
color==m_data[x][y+1]&&
color==m_data[x][y+2]&&
color==m_data[x][y+3]&&
color==m_data[x][y+4])
{
returnTRUE;
}
}
}
判断“\”方向
for(y=0;y<11;y++)
{
for(x=0;x<11;x++)
{
if(color==m_data[x][y]&&
color==m_data[x+1][y+1]&&
color==m_data[x+2][y+2]&&
color==m_data[x+3][y+3]&&
color==m_data[x+4][y+4])
{
returnTRUE;
}
}
}
判断“”方向
for(y=0;y<11;y++)
{
for(x=4;x<15;x++)
{
if(color==m_data[x][y]&&
color==m_data[x-1][y+1]&&
color==m_data[x-2][y+2]&&
color==m_data[x-3][y+3]&&
color==m_data[x-4][y+4])
{
returnTRUE;
}
}
}
不满足胜利条件
returnFALSE;
}
需要说明的一点是,由于这个算法所遵循的搜索顺序是从左到右、自上而下,因此在每次循环的时候,都有一些坐标无需纳入考虑范围。
例如对于横向判断而言,由于右边界所限,因而所有横坐标大于等于11的点,都构不成达到五子连的条件,所以横坐标的循环上界也就定为11,这样也就提高了搜索的速度。
6.2 人机对弈算法
人机对弈算法完全按照CGame基类定义的接口标准,封装在了COneGame派生类之中。
下面将对这个算法进行详细地介绍。
[14]
6.2.1 获胜组合
获胜组合是一个三维数组,它记录了所有取胜的情况。
也就是说,参考于CTable:
:
Win中的情况,对于每一个落子坐标,获胜的组合一共有
15*11*2+11*11*2=572种。
而对于每个坐标的获胜组合,应该设置一个[15][15][572]大小的三维数组。
在拥有了这些获胜组合之后,就可以参照每个坐标的572种组合给自己的局面和玩家的局面进行打分,也就是根据当前盘面中某一方所拥有的获胜组合多少进行权值的估算,给出最有利于自己的一步落子坐标。
由于是双方对弈,所以游戏的双方都需要一份获胜组合,也就是:
boolm_Computer[15][15][572];电脑获胜组合
boolm_Player[15][15][572];玩家获胜组合
在每次游戏初始化(COneGame:
:
Init)的时候,需要将每个坐标下可能的获胜组合都置为true。
此外,还需要设置计算机和玩家在各个获胜组合中所填入的棋子数:
intm_Win[2][572];
在初始化的时候,将每个棋子数置为0。
6.2.2 落子后处理
每当一方落子后,都需要作如下处理:
●如果己方此坐标的获胜组合仍为true,且仍有可能在此获胜组合处添加棋子,则将此获胜组合添加棋子数加1;
●如果对方此坐标的获胜组合仍为true,则将对方此坐标的获胜组合置为false,并将对方此获胜组合添加棋子数置为-1(不可能靠此组合获胜)。
以玩家落子为例,代码为:
for(i=0;i<572;i++)
{
修改状态变化
if(m_Player[stepPut.x][stepPut.y][i]&&
m_Win[0][i]!
=-1)
m_Win[0][i]++;
if(m_Computer[stepPut.x][stepPut.y][i])
{
m_Computer[stepPut.x][stepPut.y][i]=false;
m_Win[1][i]=-1;
}
}
6.2.3 查找棋盘空位
在计算机落子之前,需要查找棋盘的空位,所以需要一个SearchBlank成员函数完成此项工作,此函数需要进行不重复的查找,也就是说,对已查找过的空位进行标记,并返回找到空位的坐标,其代码如下:
boolCOneGame:
:
SearchBlank(int&i,int&j,
intnowTable[][15])
{
intx,y;
for(x=0;x<15;x++)
{
for(y=0;y<15;y++)
{
if(nowTable[x][y]==-1&&nowTable[x][y]!
=2)
{
i=x;
j=y;
returntrue;
}
}
}
returnfalse;
}
6.2.4 落子打分
找到空位后,需要对这个点的落子进行打分,这个分数也就是这个坐标重要性的体现,代码如下:
intCOneGame:
:
GiveScore(constSTEP&stepPut)
{
inti,nScore=0;
for(i=0;i<572;i++)
{
if(m_pTable->GetColor()==stepPut.color)
{
玩家下
if(m_Player[stepPut.x][stepPut.y][i])
{
switch(m_Win[0][i])
{
case1:
nScore-=5;
break;
case2:
nScore-=50;
break;
case3:
nScore-=500;
break;
case4:
nScore-=5000;
break;
default:
break;
}
}
}
else
{
计算机下
if(m_Computer[stepPut.x][stepPut.y][i])
{
switch(m_Win[1][i])
{
case1:
nScore+=5;
break;
case2:
nScore+=50;
break;
case3:
nScore+=100;
br
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ugtllt 五子棋 毕业论文 设计