网络五子棋的设计与实现论文.docx
《网络五子棋的设计与实现论文.docx》由会员分享,可在线阅读,更多相关《网络五子棋的设计与实现论文.docx(41页珍藏版)》请在冰豆网上搜索。
网络五子棋的设计与实现论文
摘要
五子棋游戏以其优秀的人工智能深受广大玩家的喜爱,而对于初步探究网络编成的编程爱好者来说,编制五子棋程序因其规则简单而大受欢迎,然而它却要求程序员对五子棋规则有相当深入的了解。
程序员考虑得越周到,其五子棋程序就越智能。
五子棋游戏软件设计的主要内容是:
根据五子棋的基本规则,要让对方客户端知道该在哪一点下子,就要根据盘面的形势,并把棋盘棋子的重新绘制绘制,也就是更新该点的位置,然后再通过监听网络传递的消息,直到新的位置放在棋盘的什么位置上,在进行修改,并通过计算,得出玩家是否获得胜利.,因此玩家就能反复的进行联机游戏。
本文论述了采用联机对战的方式体现出五子棋程序的分析与设计,并采用面向对象的开发工具VC++来具体实现。
关键词:
五子棋,VC++,面向对象
Abstract
Wuziqigamewithexcellentartificialintelligencebythevastnumberofplayerswho,fortheinitialresearchnetworkorganizationprogrammingenthusiasts,Wuziqiproceduresforthepreparationoftherulessimpleandpopular,butitrequiresprogrammertoWuziqigamehasadeepunderstandingoftherules.OtherthoughtfulconsiderationtheytreattheirWuziqigameproceduresmorewisdom.
Wuziqigamesoftwaredesignisthemaincontent:
AccordingWuziqibasicrulestoknoweachother'scustomers-inviolationoftheWest,wemustunderPermiansituation,andtheboardpawnre-mappingmapping,thatisupdatingthepointposition,andthenthroughthemonitoringnetworknewsuntilthenewlocationontheboardwhatposition,Followingchanges,andthroughthecalculation,resultinginplayersisvictory.,theon-linegameplayerscanrepeatedly.
Thisarticlediscussestheuseofon-linewayreflectthoseWuziqiproceduresanalysisanddesign,object-orienteddevelopmenttoolsandtheadoptionofspecificVC++toachieve.
KeyWords:
Wuziqi,VC++,object-oriented
第一章引言
1.1课题背景
1.1.1背景知识
五子棋是起源于中国古代的传统黑白棋种之一。
现代五子棋日文称之为“连珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(FiveinaRow的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。
它是中西文化的交流点,是古今哲理的结晶。
五子棋起源于古代中国,发展于日本,风靡于欧洲。
对于它与围棋的关系有两种说法,一说早于围棋,早在“尧造围棋”之前,民间就已有五子棋游戏;一说源于围棋,是围棋发展的一个分支。
在中国的文化里,倍受人们的青睐。
古代的五子棋的棋具与围棋相同,纵横各十七道。
五子棋大约随围棋一起在我国南北朝时先后传入朝鲜、日本等地。
据日本史料文献介绍,中国古代的五子棋是经由高丽(朝鲜),于1688年至1704年的日本元禄时代传到日本的。
到日本明治32年(公元1899年),经过公开征名,“连珠”这一名称才被正式确定下来,取意于“日月如合壁,五星如连珠”。
从此,连珠活动经过了不断的改良,主要是规则的变化(即对执黑棋一方的限制),例如,1899年规定,禁止黑白双方走“双三”;1903年规定,只禁止黑方走“双三”;1912年规定,黑方被迫走“双三”亦算输;1916年规定,黑方不许走“长连”;1918年规定,黑方不许走“四、三、三”;1931年规定,黑方不许走“双四”,并规定将19×19的围棋盘改为15×15的连珠专用棋盘。
本世纪初五子棋传入欧洲并迅速风靡全欧。
通过一系列的变化,使五子棋这一简单的游戏复杂化、规范化,而最终成为今天的职业连珠五子棋,同时也成为一种国际比赛棋。
1.1.2五子棋游戏的规则
(一)棋盘,棋子
1.棋盘为十五路,正中一点为“天元”,周围四点为小星。
2.棋子分黑白两色,黑子113枚,白子112枚,共225枚。
(二)比赛规则
1.黑先白后,从天元开始落子。
然后执白棋的一方在黑棋周围的交叉点上落子,白第二着棋应布在自己河界的一侧。
此后,执黑方在以天元为中心的25个交叉点的范围内布盘面的第三着棋。
2.最先在横向,竖向,斜向形成连续的相同色五个棋子的一方为胜。
3.黑棋禁手判负,白棋无禁手。
黑棋禁手包括“三三”,“四四”,“长连”。
黑方只能“四三”胜。
所谓禁手,是指黑方一子落下同时形成两个或两个以上的活三,冲四及长连禁手。
长连禁手是指黑方形成六个或六个以上的连续棋子。
4.双方均不能形成五连为和棋。
5.对局中拔子,中途退场均判为负。
6.五连与禁手同时形成,先五为胜。
因黑方已形成五连,故禁手失效,黑方胜。
7.黑方禁手形成时,白方应立即指出禁手点,黑方即负。
若白方继续应子,则黑方禁手不成立。
8.高段位职业比赛的特殊规定:
“三手可交换”:
黑下完第2手,执白者可提出交换。
即执白方变为执黑方。
“五手两打法”:
执黑下第五手时,必须下两手棋,执白者从这两手棋中任选一步。
本文所论述的联机五子棋系统就是依照这种方式进行的。
1.1.3开发系统的几点建议
(1)、开发系统不必贪大求全,力争简单实用。
应从大处着眼,小处着手,循序渐进,逐步完善。
(2)、对开发过程中的各种文档应当注意保存。
这是系统开发所要求的必要条件。
(3)、尽可能取得对程序设计重视,使用简化的程序代码保证整个系统开发的清晰。
1.2相关技术介绍
1.2.1结构化生命周期法简介
结构化生命周期法是一种传统的系统开发方法,其基本思想是把整个系统开发过程分成若干个阶段,每个阶段进行若干活动,每项活动应用一系列标准、规范、方法和技术,完成一个或多个任务,形成符合给定规范的产品。
采用结构化生命周期法来开发系统时,应遵循的主要原则:
(1)、用户参与的原则
(2)、“先逻辑后物理”的原则
(3)、“自顶向下”的原则
(4)、工作成果描述(主要指文档)标准化的原则
其具体开发步骤可分为以下四步:
a系统规划
b系统开发
c系统的运行及维护
d系统评价
其中系统开发又分为以下四个步骤:
(a)系统分析
.系统初步调查
.系统可行性研究
.现行系统的详细调查
.新系统逻辑方案的提出
(b)系统设计
.系统总体结构设计
系统总体功能设计
.系统总体物理结构设计
系统详细设计
.代码设计
.输入输出设计
(c)系统实施
.程序设计
系统测试
1.2.2开发技术——快速原型法简介
快速原型法是80年代发展起来的,旨在缩短开发周期,提高开发效率和用户对系统的满意程度。
其基本思想是在系统开发的初期,尽快构造出系统的原型,使用户能及早地运行这个系统原型,通过使用它、熟悉它,受到启发并取得经验,然后对系统的目标和功能提出更精确、具体的要求,研制人员据此逐渐修改和完善原型,使它满足用户的需求,最后完成系统的开发。
该方法大大提高了系统开发效率,弥补了结构化生命周期法来开发的时间长的缺陷。
通常采用原型法需要以下四个阶段:
(1)、明确用户的基本要求
(2)、研制系统的原型
(3)、使用、评价系统原型
(4)、修改和完善原型
1.2.3本系统开发方法的选择
基于以上开发方法的优劣和本系统的实际情况,本系统总体上采用结构化生命周期法进行系统规则、系统分析和系统设计,但在系统实施阶段采用原型法。
在开发程序的方法上,本系统将采用VISUALC++开发工具编制一个五子棋联机游戏的软件,用以实现客户端与服务端管理。
第二章系统目标
五子棋联机游戏系统主要致力于为提供联机双方进行联机游戏联络,以及提供准确可靠用户操作动作的信息。
具体目标如下:
●选择连接到服务器的客户端进行记录。
●记录客户机的键盘动作。
●分析是否已经取得胜利。
第三章系统需求分析
3.1系统需求
(1)满足记录客户机的游戏动作的基本要求。
(2)满足连接数据到客户端的基本要求。
(3)满足服务器实时获得客户端游戏状态的基本要求。
(4)在服务器端分析双方是否胜利。
3.2功能需求
基于系统需求分析,该系统需要实现以下基本功能:
(1)动作记录:
当客户端程序启动的时候,程序自动加载键盘钩子,对客户端的网络的连接和操作进行记录,并提示给游戏双方。
(2)对连接到客户端数据的基本要求:
能够将要发送的聊天记录发送至对方手上,能够完成数据的连接。
。
(3)实时显示:
当从游戏一方将数据传入另一方系统中,将五子棋的表格进行重新的刷新,和更改。
(4)通过控制鼠标点击五子棋表格:
进入控制模式,加载鼠标钩子,截取鼠标的按件动作,并把该动作发送到游戏另一方,并判断是否胜利。
3.3系统运行环境
系统运行环境:
Windows2000及其以上
3.4MFC简述
MFC(MicrosoftFoundationClass)指的是Microsoft基础类,是用来为Windows开发C++GUI应用程序。
MFC是一种十分优秀的工具,使得面向对象的软件函数包装技术演变成为一种可以进行代码复用、简化了程序的复杂性并使程序更加有效的软件开发环境..对于使用WindowsAPI进行应用程序开发的人员来说,MFC使程序员大大提高了程序开发效率.你不必创建GDU对象,不必编写许多代码行对这些对象进行初始化,并且小心地跟踪其生命周期的运行情况,你只需建立一个MFC类的实例,使用其默认值,然后让撤消程序来清除系统资源即可.
3.5服务器与客户端SOCKET设计
本程序都采用tcpsock的DLL模型,该模型允许应用程序以Windows消息的形式接收网络事件通知。
这个模型是为了适应Windows的消息驱动环境而设置的,用于对性能要求不高的网络应用程序,最大可连接64个客户端。
使用该模型基本满足本程序要求。
协议设计:
0move鼠标移动
1leftdown鼠标左件按下
2leftup鼠标左件弹起
3rightdown鼠标右件按下
4rightup鼠标右件弹起
5send发送数据
6stop停止发送
7quick实时发送
第四章系统设计
4.1概要设计
本次毕业设计的内容就是设计出联机五子棋系统,在此基础上实现系统模型各个子系统的基本功能。
此系统用建立一个tcpsock的DLL文件来进行联机的游戏的网络数据。
主要是运用了strListen类进行联机数据的传输
在系统功能需求分析的基础上,结合VisualC++程序编制的特点,得到下图所示的系统功能模块图。
图4-1五子棋服务端模块
图4-2五子棋客户端主模块
4.2流程图
下面用我们用数据流图(DFD,DataFlowDiagram),也就是从数据传递和加工的角度,以图形的方式刻画数据流从输入到输出的移动变换过程。
如下图所示:
本图只是画出了系统得一部分的功能流程图,因为本程序是一个windows程序,由较多的功能,主要是基于消息驱动的,所以有一些功能不能有流程图表达出来,如,消息的传递,当系统接到客户端传递来的信息后,就调用一个函数,将随机的产生出一些信息。
提示在提示框内。
让下棋一方了解到,现在该我下子了。
当然传递对方下棋的棋子位置等数据的接受处理也是基于消息的,当有传递数据到达的时候,系统会触发一个消息,程序调用函数读取数据并进行相应的处理。
如果是对方棋子位置的信息,则在屏幕上找到对应期盼坐标画出对方棋子,同时判断对方是否获胜。
4.3详细设计
4.3.1钩子的使用
本程序使用了以个钩子,他们分别是鼠标钩子。
客户段使用的是键盘钩子,拦截WH_KEYBOARD消息,服务器使用的鼠标钩子,当服务器要获得客户端操作的时候,鼠标钩子将用户的鼠标信息以消息的形式发送到服务器端,服务器再通过socket发送到客户端进行控制操作
因此我们必须首先了解钩子的使用函数:
HHOOKSetWindowsHookEx(intidHook,HOOK_PROClpfn,HINSTANCEhMod,DWORDdwThreadID);
参数说明:
idHook:
钩子的类型
lpfn:
钩子处理函数地址
hMod:
包含钩子函数的模块句柄
dwThreadID:
钩子的线程
函数说明:
函数将在系统中挂上一个由idHook指定类型的钩子,处理相应的特定消息。
BOOLUnhookWindowsHookEx(HHOOKhhk);
函数说明:
函数将撤销由hhk指定的钩子。
LRESULTCallNextHookEx(HHOOKhhk,intnCode,WPARAMwParam,LPARAMlParam);
函数说明:
函数将消息向下传递,下一个钩子处理将截获这一消息。
HHOOKSetWindowsHookEx(intidHook,HOOK_PROClpfn,HINSTANCEhMod,DWORDdwThreadID);
参数说明:
idHook:
钩子的类型
lpfn:
钩子处理函数地址
hMod:
包含钩子函数的模块句柄
dwThreadID:
钩子的线程
函数说明:
函数将在系统中挂上一个由idHook指定类型的钩子,监控并处理相应的特定消息。
BOOLUnhookWindowsHookEx(HHOOKhhk);
函数说明:
函数将撤销由hhk指定的钩子。
LRESULTCallNextHookEx(HHOOKhhk,intnCode,WPARAMwParam,LPARAMlParam);
函数说明:
函数将消息向下传递,下一个钩子处理将截获这一消息。
4.4程序设计
4.4.1程序窗口的设计
由于此应用程序采用的是基于对话框的开发,系统应用程序的各个不同功能是通过选择主对话框窗口中的不同按钮来完成的,每个功能模块由一个或多个对话框实现。
该应用程序的主对话框(即运行应用程序后出现的对话框)如图所示:
本文系统得棋盘是由本文设定的画笔进行绘画而成的。
布尔值对数据进行更新和计算,将棋盘和棋子很好的合并在一起。
这样整个五子棋的程序将很轻易的展现在人们的面前
建立好后,就可以输入代码:
voidCMyChessDlg1:
:
DrawNowBlack(intx,inty)
{
//画当前的黑子
CClientDCdc(this);
CDCmdc;
mdc.CreateCompatibleDC(&dc);
mdc.SelectObject(m_bblack);
dc.BitBlt(24+x*36-x-18,25+y*36-y-18,33,33,&mdc,0,0,MERGEPAINT);
mdc.SelectObject(m_blastblackchess);
dc.BitBlt(24+x*36-x-18,25+y*36-y-18,33,33,&mdc,0,0,SRCAND);
}
voidCMyChessDlg1:
:
DrawNowWhite(intx,inty)
{
//画当前的白子.
CClientDCdc(this);//CClientDC类负责在构造时调用Windows函数GetDC,在析构时调用ReleaseDC
CDCmdc;
mdc.CreateCompatibleDC(&dc);//CreateCompatibleDC()函数创建一个与&dc指定的设备兼容的内存设备描述表
mdc.SelectObject(m_bblack);//SelectObject()将一个对象引入设备描述表
dc.BitBlt(24+x*36-x-18,25+y*36-y-18,33,33,&mdc,0,0,MERGEPAINT);//MERGEPAINT用布尔OR操作符将反相的源位图与目标位图结合起来
mdc.SelectObject(m_blastwhitechess);
dc.BitBlt(24+x*36-x-18,25+y*36-y-18,33,33,&mdc,0,0,SRCAND);//SRCAND用布尔AND操作符将目标位图象素与源位图象素结合起来
}
voidCMyChessDlg1:
:
GetBoard(inttempboard[][15],intnowboard[][15])//获取当前棋盘状态
{
inti,j;
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
if(i==9)
i=9;
tempboard[i][j]=nowboard[i][j];
}
}
voidCMyChessDlg1:
:
InitializeBoard()//初始化
{
//初始化函数
inti,j,count=0,k;
m_pclastpos.x=-1;
m_pclastpos.y=-1;
m_pplastpos.x=-1;
m_pplastpos.y=-1;
start=true;
//判断哪方先开始
if(m_bwfirst)//计算机先
{
player=false;
computer=true;
}
else//人先
{
player=true;
computer=false;
}
pwin=cwin=false;//初始化计算机和玩家的获胜组合情况
for(i=0;i<15;i++)
for(j=0;j<15;j++)
for(k=0;k<572;k++)
{
ptable[i][j][k]=false;
ctable[i][j][k]=false;
}
for(i=0;i<2;i++)
for(j=0;j<572;j++)
win[i][j]=0;
for(i=0;i<15;i++)
for(j=0;j<15;j++)
board[i][j]=2;
for(i=0;i<15;i++)
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i][count]=true;
ctable[j+k][i][count]=true;
}
count++;
}
for(i=0;i<15;i++)
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
ptable[i][j+k][count]=true;
ctable[i][j+k][count]=true;
}
count++;
}
for(i=0;i<11;i++)
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i+k][count]=true;
ctable[j+k][i+k][count]=true;
}
count++;
}
for(i=0;i<11;i++)
for(j=14;j>=4;j--)
{
for(k=0;k<5;k++)
{
ptable[j-k][i+k][count]=true;
ctable[j-k][i+k][count]=true;
}
count++;
}
}
voidCMyChessDlg1:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
intx,y,tx,ty;
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if(player&&point.x<=535&&point.y<=535)//判断是否在有效区域
{
tx=x=point.x-24;
ty=y=point.y-25;
while(tx>=36)
tx-=36;
while(ty>=36)
ty-=36;
tx+=x/36;
ty+=y/36;
if(tx>18)
x=x/36+1;
else
x=x/36;
if(ty>18)
y=y/36+1;
else
y=y/36;//将坐标换算成棋盘上的格子。
if(board[x][y]==2)
{
board[x][y]=0;//设为玩家的棋子
if(m_pplastpos.x!
=-1&&m_pplastpos.y!
=-1)
{
if(!
m_bwfirst)
DrawWhiteChess(m_pplastpos.x,m_pplastpos.y);
else
DrawBlackChess(m_pplastpos.x,m_pplastpos.y);
}
if(!
m_bwfirst)
DrawNowWhite(x,y);
else
DrawNowBlack(x,y);
m_pplastpos.x=x;//将当前棋子的信息装入,记录移动棋子的结构中
m_pplastpos.y=y;
for(inti=0;i<572;i++)
{//修改玩家下子后棋盘状态的变化
if(ptable[x][y][i]&&win[0][i]!
=7)
win[0][i]++;