《2022年网络编程基础实训报告 .pdf》由会员分享,可在线阅读,更多相关《2022年网络编程基础实训报告 .pdf(20页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、网络编程基础实训报告题目:五子棋人机博弈游戏院(系):计算机与通信工程学院专业:信息安全姓名:班级:信息安全学号:指导教师:2012 年 10 月 12 日名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 20 页 -目录一系统需求分析与总体设计1.需求分析 问题描述 数据流程图2.总体设计 开发背景 开发语言 总体功能设计二详细设计与系统实现1.类和类的方法设计 类的设计 类的方法设计三系统测试1.功能测试四总结1.系统仍存在的不足2.结论和体会一系统需求分析与总体设计1.需求分析 问题描述名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 20 页 -题目:五子棋人机
2、博弈游戏题目要求:实现五子棋游戏的人机博弈。要求:友好的人机图形化界面、方便的操作方式;自动判断输、赢或平;可选择黑白;可悔棋;可以基于人工智能方面的知识进行设计,如:启发式搜索、搜索函数的设置、_算法、知识的表示及知识库,推理机等。五子棋简介:五子棋是起源于中国古代的传统黑白棋种之一。顾名思义,只要连成五子即可获得胜利。听上去好像很简单,但是不用技巧好似很难获胜的,这其中就有“活三”,“冲三”等等专业名词,这些我会在后续的程序中进行介绍。五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单
3、易学的特性,为人民群众所喜闻乐见。通过问题的描述,初步分析可得出此软件应具有以下的功能:1.友好的界面,方面的操作方式可以快速开始游戏,功能明确而且界面明朗2.自动判断输赢计算机可以根据棋子的状态判断胜负情况3.可选择黑白可以先手下棋和后手下棋4.可悔棋具有悔棋功能5.计算机 AI 计算机需要具有一定的AI,需要 AI 攻守兼备数据流程图数据流动很少,主要是在算法内部进行计算,实际进行交互的数据是没有的。要求开始游戏落子,33 禁手棋子坐标玩家落子取最佳位置并落子(若不分胜负)再来一盘胜负已分2.总体设计 开发背景C#网络编程基础实训通过这个程序学习基本的c#网络编程。玩家计算机 AI:即算法
4、判断谁是先手输赢判断是否再来一盘名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 20 页 -语言选择使用 C#平台在设计人机界面时更人性化,画图工具也更为简洁易用。具体功能设计主要函数:1.画棋子2.画棋盘3.先手判断4.胜负判断5.计算机 AI 算法(权值赋值,权值计算,找最大权值)界面设计:1.快速开始游戏2.先手选择3.悔棋,认输,电脑提示4.棋子的坐标显示(计算电脑提示的附加功能)5.帮助这几个模块的重点是计算机AI 算法的设计。在参阅了很多资料以后,我发现解决五子棋问题的算法非常之多,遗传算法,剪枝算法等等,这些算法的特点是对后续步骤进行无数次的推演并一一评分,最后去评
5、分最高的一种方案的第一步,在下完一子之后再进行算法计算,虽然AI 非常聪明但是计算繁琐且计算时间其长无比。在网上发现的算法有更多的程序员是采用了权值计算的方法,具体来说就是根据每种情况每种可能对每个点都赋不同的权值,AI 在判断应该进攻还是应该防守就是依靠权值的大小,权值最大的位置放棋子,采用这种方法虽然笨是笨了些,但是计算速度快,尤其是在棋盘比较小的时候(15*15 棋盘),而且在对比中发现这种AI 也很聪明。在速度和计算精度之间权衡之后,我准备选择计算权值的方法来做,如果时间仍有富裕的话再使用别的算法来计算并进行对比。二详细设计与系统实现1.类和类的方法设计 类的设计(后面的方法设计也遵从
6、这个顺序逐个进行详细注释)棋盘类 Chessboard 棋盘类主要实现对棋盘棋子,以及电脑和人下棋的显示,对虚拟棋盘的定义,对下棋路径的堆栈的初始化,对棋局的初始化。棋子类 Stone 棋子类主要实现对棋子的画图操作。计算机类 Computer 计算机类是本程序的核心模块,主要实现计算机对每个棋子每个位置的权值赋值,对每个棋盘位置的权值计算,求最大权值。名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 20 页 -规则类 Rule 规则类主要实现对胜负平局的判断,对黑棋禁手的判断,对每个方向上的连子数的计算,对棋局判断是依据连子数计算的。主函数类 frmMain 主函数主要是对界面
7、上每个按键的功能进行实现,另实现对鼠标的move 和 click 事件的定义,获取鼠标的坐标。类的方法的具体实现1.Chessboard类中方法的实现一Chessboard中的变量定义所谓的在棋盘上下棋,其实就是在相应坐标进行绘图,实际是不存在棋盘的,这里我定义一个 15,15 的二维数组来表示虚拟的棋盘进行下棋,其他见程序注释。publicint,arrchessboard=new int 15,15;/arrchessboard为棋盘情况数组,虚拟棋盘的定义,arrchessboardi,j=2表示此处无子arrchessboardi,j=0表示此处为黑子,arrchessboardi,j
8、=1表示此处为白子privateGraphics mg;/绘制的对象publicStone stone;/棋子对象publicComputer computer;/电脑对象privatebool stoneflag=true;/判断当前棋子是黑(true)是白(false)privatebool mplayfirstflag=false;/判断先手玩家(是电脑(true)还人(false),先手下黑棋)privateStack mStarckHistory=new Stack();/历史记录堆栈二Chessboard中对棋盘和棋子的绘制对棋子和棋盘的绘图要用到system.draw 这个系统自
9、带的画图类,我使用的方式是先读取文件流中的文件,然后在每次画图的时候就不用再次读取了,直接可以进行绘图,这样处理速度比较快。详细见注释。publicvoid Draw()/从资源中获取,读取棋盘图像,就是在当前项目中读取文件System.Reflection.Assembly thisExe;thisExe=System.Reflection.Assembly.GetExecutingAssembly();System.IO.Stream file=thisExe.GetManifestResourceStream(FiveStones.chessboard.gif);/棋盘文件Image i
10、mgChessboard=System.Drawing.Image.FromStream(file);/棋盘图片大小*600像素,每个棋子的点的坐标,个棋子,个空,两边线留空file.Close();mg.DrawImage(imgChessboard,0,0,imgChessboard.Width,imgChessboard.Height);/绘制棋子for (int i=0;i15;i+)for(int j=0;j15;j+)名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 20 页 -if (arrchessboardi,j=0)/对棋盘上的点进行判断后,根据虚拟数组的值来判
11、断绘制哪一种棋子 stone.DrawStone(i,j,true);/Stone 里面具体的绘制方法 if (arrchessboardi,j=1)stone.DrawStone(i,j,false);三Chessboard 中人下棋和电脑下棋就是获取下棋的坐标,然后在该坐标进行相应的绘图,然后把该点的虚拟棋盘置成2,表示已经下过棋了。publicvoid PersonDownStone(int x,int y)if (x 600&y 100)/如果下一百个子还不分胜负,就直接异常退出 MessageBox.Show(异常!);Start();return;名师资料总结-精品资料欢迎下载-名
12、师精心整理-第 6 页,共 20 页 -while(Rule.IsExist(m,n,arrchessboard);/当判断该点没有子的时候下子DownStone(m,n);四Chessboard对棋局的初始化把初始化贴上来的目的是为了让每次下棋的流程更明显,构造对象啊,还有清空堆栈呀,这些看似很简单,但是其中的顺序是不可颠倒的,详细见注释。privatevoid Initialization()/棋盘初始化 stoneflag=true;/置当前要走的棋为黑棋(黑棋先走)for(int i=0;i15;i+)for(int j=0;j15;j+)arrchessboardi,j=2;/把棋盘
13、所有位置置为空(未下子)mStarckHistory.Clear();/清空历史记录堆栈stone=new Stone(mg);/构造棋子对象 privatevoid Start()/这个才是初始化函数 Initialization();computer=new Computer(mplayfirstflag);/构造电脑对象Draw();/画棋盘if (mplayfirstflag)/如果是电脑先手的话就电脑下棋,否则等待 ComputerDownStone();五Chessboard 中每下一子都要进行的处理做法,更改虚拟棋盘的数值,对禁手进行判断,将棋子坐标压入堆栈,下棋完成后交换下棋。
14、这个过程显示了下棋的步骤,在下棋之后,对虚拟棋盘也就是二维数组进行赋值,然后把该点压入堆栈,然后对黑棋是否禁手进行判断,这里用到了Rule 传过来的值,详细见注释。privatevoid DownStone(int m,int n)stone.DrawStone(m,n,stoneflag);/下棋if (stoneflag)/记录情况 arrchessboardm,n=0;/根据黑白标记对虚拟棋盘数组进行赋值 else arrchessboardm,n=1;名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 20 页 -i f (stoneflag)/记录历史记录压入堆栈/压入堆栈
15、的是棋子颜色和坐标mStarckHistory.Push(黑:+m.ToString()+,+n.ToString();else mStarckHistory.Push(白:+m.ToString()+,+n.ToString();if (Rule.Result(m,n,arrchessboard)6)/判断结果,这个要调用Rule中的方法 switch(Rule.Result(m,n,arrchessboard)/禁手失败直接判黑棋负,重新开始 case 1:MessageBox.Show(黑棋双三禁手失败!);break;case 2:MessageBox.Show(黑棋双四禁手失败!);
16、break;case 3:MessageBox.Show(黑棋长连禁手失败!);break;case 4:if (stoneflag)MessageBox.Show(黑棋胜利!);else MessageBox.Show(白棋胜利!);break;case 5:MessageBox.Show(平局!);break;Start();/重新开始!return;else stoneflag=!stoneflag;/交换当前棋子颜色 由 Rule.Rusult的返回值进行判断,这几种情况都要重新开始!每下一子就压入堆栈名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 20 页 -2.Sto
17、ne类中方法的实现 Stone 类主要实现的就是对棋子的绘图,没什么好说的。publicclassStone privateGraphics mg;privateImage imgBlackStone;/黑子图片从文件获取privateImage imgWhiteStone;/白子图片public Stone(Graphics g)System.Reflection.Assembly thisExe;thisExe=System.Reflection.Assembly.GetExecutingAssembly();System.IO.Stream wfile=thisExe.GetManife
18、stResourceStream(FiveStones.whitestone.gif);/读取黑子,白子图片System.IO.Stream bfile=thisExe.GetManifestResourceStream(FiveStones.blackstone.gif);/从资源中获取 imgBlackStone=System.Drawing.Image.FromStream(bfile);imgWhiteStone=System.Drawing.Image.FromStream(wfile);bfile.Close();wfile.Close();mg=g;publicvoid Draw
19、Stone(int m,int n,bool flag)/绘制棋子 if (flag)/判断是黑棋(true)还是白棋(false)g.DrawImage(imgBlackStone,m*40,n*40,imgBlackStone.Width,imgBlackStone.Height);else g.DrawImage(imgWhiteStone,m*40,n*40,imgWhiteStone.Width,imgWhiteStone.Height);3.Computer 类中方法的实现一每下一子都要进行的过程 Down方法这个方法说明了下子之后的整个计算过程,先重新定义一个虚拟棋盘,然后对该虚
20、拟棋盘有子的位置的权值赋值为-1,就是肯定不会走的,然后调用Check方法对没有子的位置进行权值计算,然后使用Check返回的权值在 MaxQZ 里面计算权值的最大值。publicvoid Down(int,arrchessboard)/基本思路:先计算每个点的权值,在权值最高的位置下棋 int ,qz=new int 15,15;/权值数组for (int i=0;i15;i+)对棋子的绘制方法,需要从当前目录进行读取图片,再绘制绘制棋子名师资料总结-精品资料欢迎下载-名师精心整理-第 9 页,共 20 页 -for(int j=0;j15;j+)if (arrchessboardi,j 2
21、)qzi,j=-1;/当已有子时标注为-1 else qzi,j=Check(i,j,arrchessboard);/Check 方法在下面介绍,是计算权值的方法 MaxQZ(qz);/MaxQZ也在下面进行介绍,是计算最大权值的方法 二计算权值的方法Check 上面的流程图写出了整体的过程,Check主要是对刚刚定义的权值数组进行赋值,先对己方进行赋值,然后对对手的进行赋值,然后判断是应该防守还是应该进攻。电脑 Ai 的攻击力取决于权值的赋值,详细见注释。privateint Check(int m,int n,int,arrchessboard)/赋值的原则决定了AI 是进攻强还是防守强,
22、进攻强则在AI 和人都有三字连起时,给自己的赋值更高一些,防守强则是给人的赋值更高一些int qz=0;int w1=100000;/找自己的取胜点()int w2=50000;/找对手的取胜点()int w3=10000;/找自己的三个相连的点()int w4=5000;/找对手的三个相连的点()int w5=1000;/找自己的两个相连的点()int w6=500;/找对手的两个相连的点()int w7=100;/找自己的相连的点()int w8=50;/找对方的相连的点()int w9=999999;/找自己的失败点,无穷大,优先胜利int arrf=new int 4;if (mfla
23、g)/如果电脑是黑子 arrchessboardm,n=0;/如果该位置下我方的子的时候,进行下面的权值计算,赋权值赋权值的原则根据当前点调用Rule 的方法计算连子对 当 前颜 色 的连 子 进行 赋 权值给对手颜色的连子点赋权值返回权值名师资料总结-精品资料欢迎下载-名师精心整理-第 10 页,共 20 页 -白黑子都要进行计算 else/否则电脑是白子 arrchessboardm,n=1;/这里赋值的原因是因为不同色的值不一样/分别计算四个方向上的连子数,调用Rule里面的四个方法arrf0=Rule.Xnum(m,n,arrchessboard);/横向 arrf1=Rule.Ynu
24、m(m,n,arrchessboard);/竖向arrf2=Rule.YXnum(m,n,arrchessboard);/左上右下arrf3=Rule.XYnum(m,n,arrchessboard);/右上左下if (m=7&n=7)qz+=1;/中心点权值加,这主要是为了电脑先手时,优先走中间点for (int i=0;i0)qz+=w9;if (mflag)/如果该位置下对方的子 arrchessboardm,n=1;/对方白子 else/对方黑子 赋值的过程!判断是否是禁手点,调用 Rule 里面的方法名师资料总结-精品资料欢迎下载-名师精心整理-第 11 页,共 20 页 -arrc
25、hessboardm,n=0;arrf0=Rule.Xnum(m,n,arrchessboard);arrf1=Rule.Ynum(m,n,arrchessboard);arrf2=Rule.YXnum(m,n,arrchessboard);arrf3=Rule.XYnum(m,n,arrchessboard);for (int i=0;i4;i+)if (Math.Abs(arrfi)=5)qz+=w2;if (arrfi=4)qz+=w4;if (arrfi=3)qz+=w6;if (arrfi=2)qz+=w8;arrchessboardm,n=2;/计算结束后对该点设置成没有子retu
26、rn qz;/返回权值 三计算最大权值点比较,赋值,得出结果,没什么好说的。privatevoid MaxQZ(int ,qz)/计算最大权值/没什么好解释的。int max=0;for (int i=0;i15;i+)for(int j=0;jmax)x=i;y=j;max=qzi,j;计算你的对手的权值,然后赋值!名师资料总结-精品资料欢迎下载-名师精心整理-第 12 页,共 20 页 -4.Rule 类中的方法的实现一 计算每个方向上的连子数总体思路是在当前点分别向两边进行搜索,如果两边的点和当前点颜色一致则连子数加 1,直到碰到和当前点不一样颜色的点。不同颜色的点有三种,分别是空白点,
27、另一种颜色的点,棋盘边缘。对于空白点,则置成活棋并返回值,如果是另一种颜色的点则置成死棋并返回值,对于棋盘边缘也置成死棋并返回值。详细见注释。PS.一共有四个方向的连子数的计算,仅列出X轴的计算方法publicstaticint Xnum(int m,int n,int,arrchessboard)int flag=0;/检查是否无子可下(当flag=2 时表示无子可下)/为什么 flag=2 的时候就不能下子了呢?/是因为只有左右两边都没有棋子下的时候才结束计算权值,其他方向的检测和这个是一个原理的,/就是两头的两个方向都是对方的子了int num=1;/连子个数int i=m+1;/正东方
28、向检查(x+)while(i=0)if (arrchessboardi,n=arrchessboardm,n)/前方的棋子与 m,n点不是一样的棋子时跳出循环 num+;i-;else break;if (i=-1)/正西方向超出棋格 flag+;else if(arrchessboardi,n!=2)/正西方向有别的子不可在下 flag+;if (flag=2)return -num;名师资料总结-精品资料欢迎下载-名师精心整理-第 14 页,共 20 页 -else /连子数为时有一边不能下就不是活三不是活三的时候赋值降低if (flag=1&num=3)return -num;else
29、return num;二 胜负平局判断,禁手判断任意方向上连成五子即算胜利,在没有一个连成五子的情况下棋盘走满算平局,禁手判断是对当前点的四个方向计算上有三个以上连子就算禁手(仅黑子有禁手),禁手直接判负重新开始。详细见注释。胜利判断:privatestaticbool IsWin(int arr)for (int i=0;i4;i+)if (Math.Abs(arri)=5)returntrue;returnfalse;平局判断:privatestaticbool IsTie(int,arrchessboard)/当所有位置都有子时为平局for (int i=0;i15;i+)for (in
30、t j=0;j15;j+)if (arrchessboardi,j=2)returnfalse;returntrue;当连子数为5 的时候就胜利了,arrI是四个方向的连子数当所有点都有子的时候即判断为平局名师资料总结-精品资料欢迎下载-名师精心整理-第 15 页,共 20 页 -负局判断:(要对禁手进行判断,比较难)publicstaticint IsFail(int arr,int stoneflag)if (stoneflag=1)/如果是白棋不验证因为白棋无禁手 return 0;else int num=0;/活的子相连的个数for (int i=0;i 1)return 1;num
31、=0;/活的子相连的个数for (int i=0;i 1)return 2;for (int i=0;i 5)return 3;return 0;白棋没有禁手双三和双四都是活三和活四,这里定义的NUM 是为了记录活子的个数,只有有活子的双三双四才禁手名师资料总结-精品资料欢迎下载-名师精心整理-第 16 页,共 20 页 -6.frmMain 类中方法实现frmMain中的方法主要是实现窗口中的按钮,这里只对获取鼠标的坐标的功能,还有悔棋功能,电脑提示功能进行详解。一获取鼠标的坐标为什么要说获取鼠标坐标的方法呢,主要是因为其中的强制转换还有求坐标的方法当时想了很久,个人感觉有用,所以就记下来了
32、。privatevoid frmMain_MouseMove(object sender,System.Windows.Forms.MouseEventArgs e)if (e.X 600&e.Y 600)/取下棋点int m=(int)Math.Floor(double)e.X/40);int n=(int)Math.Floor(double)e.Y/40);lblXY.Text=X:+m.ToString()+Y:+n.ToString();一 系统测试一 功能测试五子棋要求实现的功能主要有:友好的人机图形化界面、方便的操作方式;自动判断输、赢或平;可选择黑白;下面通过功能测试截图进行说明
33、:1.友好的人机图形化界面,方便的操作方式,可选黑白棋名师资料总结-精品资料欢迎下载-名师精心整理-第 17 页,共 20 页 -2.自动判断胜负名师资料总结-精品资料欢迎下载-名师精心整理-第 18 页,共 20 页 -名师资料总结-精品资料欢迎下载-名师精心整理-第 19 页,共 20 页 -二 总结1.程序仍存在的漏洞和不足五子棋的程序虽然实现了游戏的大部分功能但是还有不少的功能没有实现2.结论和体会通过这次实训让我了解了c#语言,同时对网络编程这一块也有了比较详细的了解对各种协议的实现也有了深入的了解。总之这次实训让我学到了很多有用的东西为自己的以后拓宽了道路。在这里对这次实训的指导老师表示衷心的感谢!名师资料总结-精品资料欢迎下载-名师精心整理-第 20 页,共 20 页 -