人工智能实习报告(

上传人:daj****de2 文档编号:120516507 上传时间:2022-07-17 格式:DOCX 页数:34 大小:207.01KB
收藏 版权申诉 举报 下载
人工智能实习报告(_第1页
第1页 / 共34页
人工智能实习报告(_第2页
第2页 / 共34页
人工智能实习报告(_第3页
第3页 / 共34页
资源描述:

《人工智能实习报告(》由会员分享,可在线阅读,更多相关《人工智能实习报告((34页珍藏版)》请在装配图网上搜索。

1、人工智能课程设计报告姓名:班级:191092学号:-指导老师:2011年10月经过近一周的奋战,我终于初步实现了我的“四子棋”游戏。起初,我选 择这个游戏是因为它很独特、少有人做,而且我想当然的认为四子比五子少一子, 实现起来应该相对简单,但是面对一个个头疼的错误,遭受一次又一次失败的打 击,我才发现自己想错了,四子棋人机对战比五子棋更让人纠结。暑期我和班上两名同学xxx,xx 一起完成过五子棋和黑白棋的编程。当时, 五子棋我们是参照别人的模板完成的,黑白棋是在透彻研究过五子棋的基础上不 断讨论、优化算法最终完成的。现在,他们一个继续做五子棋一个做黑白棋,将 其完善作为人工智能的课程设计课题。

2、我只得另陌新路,关注起了四子棋。界面的搭建以及二人对战的实现只用了我两个晚上的时间,当然我的界面 构建的相对简单。二人对战实现关键一步就是输赢判断函数judge()的编写。 人机对战整整折腾了自己四五天的时间,我本来对于博弈过程中alphabeta剪 枝算法很理解的,但是具体要自己编程实现时我觉得自己只了解到其皮毛。所以, 我不断看五子棋程序、单步跟踪、寻问同学,终于算是把其递归和剪枝过程搞得 明明白白。花了两天完成了 alphabeta剪枝算法我本以为核心都解决了,却不知更让 人头疼的是评估函数的确定还有统计当前棋局状况的函数Calculate()的编写。 难题终究是可以被客服的,我花了整整

3、一天写完了我的Calculate()函数。直至10月27日上午我依然没有让机器足够智能,或者说它目前很呆板。 我一直在找原因,自己的模块设计算法思路都是对的,请教过同学她也觉得设计 思路没有错。现在,我整体的想了一下,觉得应该是我的静态评估函数设计的不 够合理,或者说目前的设计方法对于五子棋很合理但是对于规则不同的四子棋就 可能存在缺陷。既然目前时间不允许没能实现足够智能,那就只能把这粗略的程 序提交。我一定会继续完善、改进算法,重新设计评估函数,争取让机器达到理 想的“智能”。一、课题选则1. 题目概述利用VC+实现四子棋游戏,要求提供可视化界面以及二人对战、人机对战的功能。 四子棋游戏规则

4、如下:四子棋的棋盘共有7行7列,棋盘是垂直摆放,每名玩者只能左右控制落子的位置。 两名玩者轮流每次把一只棋子放进棋盘任何未全满的一行中,棋子会估据一行中最底未 被估据的位置。两名玩者任何一方先以四只棋子在横,竖或斜方向联成一条直线,便可 获胜,游戏亦结束。假如棋盘已完全被棋子填满,但仍未有任何一方成功把四只棋子成 一直线,则成为和局。2. 选题缘由四子棋游戏规则独特,所以其规则的设计将有别于五子棋等通常的棋类游戏。四子棋人机对战功能的实现需要用到博弈树搜索中的核心算法:。与五子棋不同,因为四子棋的独特性网络中根本没有某某“热心”网友的游戏源码, 我找了很久也只找到一个二人对战的四子棋,他还是用

5、C语言在dos下实现的,一点 也不人性化。综合以上种种我决定挑战一下自己,用VC实现“我的四子棋”游戏。二、需求分析1. 功能需求1.1提供合理的人机交互界面1.2提供二人对战功能1.3提供人机对战功能2. 数据结构2.1棋盘数据采用一二维数组grid77 存储三、模块设计A. 整体思路通过对需求的分析,我认为我的设计工作主要可以分为三大块,第一块是主界面的 搭建和棋盘的绘制,第二块是落子和输赢判断的实现,第三块就是二人对战和人机对战 的实现。对于第一块,因为有图形学和图像处理的上机经验,我将果断的选择单文档作为界 面窗口,用绘制的方式搭建棋盘。对于第二块,对于落子其实就是在响应鼠标左键按下的

6、消息后记录下所需放子的坐 标,然后改变内部存储数据,调用绘图函数ondraw ()进行绘制。输赢判断就是对于 每下一颗棋子搜索其横向竖向交叉斜向的棋子,如若有四颗连成一线的就判为赢。对于第三模块,这是整个游戏的核心,二人对战相对好实现。人机对战需要用到博 弈树搜索需要用到alphabeta剪枝算法,还需要设定以静态评估函数,这两方面是最困 难也是最重要的部分。B. 具体设计1. 主界面设计1.1单文档窗口大小的限定我们知道通过VC+工程创建的单文档都有默认的大小,那个大小太大不适合 作为游戏的界面窗口大小。所以我希望自定义其大小,而且在此游戏中不需要用工 具栏,所以我希望通过人为操作去掉工具栏

7、。具体实现:在Frame框架类里面的PreCreateWindow()创建窗口函数总添加以下代码cs.style&=WS_MAXIMIZEBOX;禁止对文档最大化操作cs.style&=WS_THICKFRAME;cs.cx=700;/自定义文档大小cs.cy=500;cs.y=180;cs.x=300;cs.style&=FWS_ADDTOTITLE;/将 FWS_ADDTOTITLE 去掉cs.lpszName=我的四子棋”;改变文档标题将OnCreate(LPCREATESTRUCT lpCreateStruct函数中以下代码屏蔽即可去掉工具栏/*if (!m_wndToolBar.Cr

8、eateEx(this, TBSTYLE_FLAT, WS_CHILD I WS_VISIBLE I CBRS_TOPI CBRS_GRIPPER I CBRS_TOOLTIPS I CBRS_FLYBY I CBRS_SIZE_DYNAMIC) II!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)TRACE0(Failed to create toolbarn);return -1;/ fail to create*/1.2棋盘绘制棋盘绘制在view类里面的ondraw函数里实现,创建画笔蓝色画笔通过 MoveTo、LineTo函数画出棋格,创建天蓝色画刷绘制

9、棋格背景色。创建红色、黄 色画刷用于绘制双方棋手棋子。具体代码如下:CRect rect;CBrush *brush,*brush1,*brush2,*brush3;brush = new CBrush;brush1 = new CBrush;brush2 = new CBrush;brush3 = new CBrush;brush-CreateSolidBrush(RGB(150, 205 ,205); _ brush1-CreateSolidBrush(RGB(255, 0 ,0);/红色画刷 brush2-CreateSolidBrush(RGB(255, 255 ,0);/黄色画刷 b

10、rush3-CreateSolidBrush(RGB(128, 128 ,28);/bai 色画刷 this-GetClientRect(&rect);pDC-FillRect(&rect,brush);CClientDC dc(this);CPen m_pen(PS_SOLID,1,RGB(0,0,255);将画笔选入设备列表CPen *pOldPen = dc.SelectObject(&m_pen);int i;for(i=0;i8;i+)dc.MoveTo(bx,by+width*i);dc.LineTo(bx+width*7,by+width*i);for(i=0;i8;i+)dc.

11、MoveTo(bx+width*i,by);dc.LineTo(bx+width*i,by+width*7);for (i=0;i7;i+)for (int j=0;jSelectObject(brush1);pDC-Ellipse(bx+width*(i+0.5)-r,by+width*(j+0.5)-r,bx+width*(i+0.5)+r,by+width*(j+0.5)+r);break;case 2:/pDC-SelectStockObject(WHITE_PEN);pDC-SelectObject(brush2);pDC-Ellipse(bx+width*(i+0.5)-r,by+

12、width*(j+0.5)-r,bx+width*(i+0.5)+r,by+widt h*(j+0.5)+r);/pDC-SelectStockObject(BLACK_PEN);break;case 3:pDC-SelectObject(brush3);pDC-Ellipse(bx+width*(i+0.5)-(r+5),by+width*(j+0.5)-(r+5),bx+width*(i+0.5)+( r+5),by+width*(j+0.5)+(r+5);break;default:break;2. 模式选择设计2.1更改菜单按钮在菜单栏中添加模式按钮“二人对战”和“人机对战”箱室莅;游

13、裁规则QJ入机对战2.2响应选择按钮消息通过MFC类向导在View类中响应“二人对战”和“人机对战”的按钮消息, 实现方式如下:void CMYSIZIQIView:OnPvsp()/ TODO: Add your command handler code herereset();pvsp=true;Invalidate();/是当前窗口无效,需要重绘void CMYSIZIQIView:OnPvsc()/ TODO: Add your command handler code herereset();pvsc=true;RorY=true;pvsp=false;Invalidate();/是

14、当前窗口无效,需要重绘3.Onleftbuttondown()函数设计3.1根据鼠标坐标转换出在存储数组中对应的下标int px=(point.x-bx)/width;int py=(point.y-by)/width;3.2限定落子只可以在该列最下面一个空格for(int j=6;j=0;j-)if(gridpxj=0)py=j;break;3.3二人对战、人机对战程序响应if(0=px&px7&0=py&py=0;i-)/&棋 子左边/MessageBox(红赢”);if(gridiy=color) HWIN+;if(gridiy!=color) break;if(HWIN=4&color

15、=1)/左边可能已经三个棋子for ( i=x-1;i=0;i-)/一方赢了则改变其颜色if(gridiy=color)gridiy=3;gridxy=3;MessageBox(红赢”);reset();Invalidate();return true;else if (HWIN=4&color=2)for ( i=x-1;i=0;i-)/一方赢了则改变其颜色if(gridiy=color)gridiy=3;gridxy=3;MessageBox(黄赢”);reset();Invalidate();return true;t0=HWIN;for (i=x+1;i=4&color=1)for (

16、 i=x+1;i=4&color=2)for ( i=x+1;i=6;i+)/一方赢了则改变其颜色if(gridiy=color)gridiy=3;gridxy=3;if(HWIN-t0=2) gridx-1y=3;if(HWIN-t0=1) gridx-1y=3;gridx-2y=3; MessageBox(黄赢”); reset();Invalidate();return true;具体判断细节见注释4.2竖向判断是否四子连线* 竖向判断 */int SWIN=1;for ( j=y+1;j=4&color=1)/T边可能已经三个棋子for (j=y+1;j=6;j+)/一方赢了则改变其颜

17、色 if(gridxj=color&j-y=4&color=2)for (j=y+1;j=6;j+)/一方赢了则改变其颜色 if(gridxj=color&j-y=0&j=0;i-,j-)/&棋 子左上方/MessageBox(红赢”);if(gridij=color) LRWIN+;if(gridij!=color) break;if(LRWIN=4&color=1)/左上可能已经三个棋子for (i=x-1,j=y-1;i=0&j=0;i-,j-) 一方赢了则改变其颜色if(gridij=color&(y-j=4&color=2)for (i=x-1,j=y-1;i=0&j=0;i-,j-

18、) 一方赢了则改变其颜色if(gridij=color&(y-j=3)gridij=3;gridxy=3;MessageBox(黄赢”);reset();Invalidate();return true;t0=LRWIN;for (i=x+1,j=y+1;i=6&j=4&color=1)for (i=x+1,j=y+1;i=6&j=6;i+,j+) 一方赢了则改变其颜色if(gridij=color&(j-y)=4&color=2)for (i=x+1,j=y+1;i=6&j=6;i+,j+) 一方赢了则改变其颜色if(gridij=color&(j-y)=3)gridij=3;gridxy=

19、3;if(LRWIN-t0=2) gridx-1y-1=3;if(LRWIN-t0=1) gridx-1y-1=3;gridx-2y-2=3;MessageBox(黄赢”);reset();Invalidate();return true;具体判断细节见注释4.4右上左下方向判断是否四子连线,2“L -f nr tt /* 右上左下力向*/int RLWIN=1;for (i=x+1,j=y-1;i=0;i+,j-)/&棋 子右上方if(gridij=color) RLWIN+;if(gridij!=color) break;if(RLWIN=4&color=1)/可能已经三个棋子for (i

20、=x+1,j=y-1;i=0;i+,j-) 一方赢了则改变其颜色if(gridij=color&(y-j=4&color=2)for (i=x+1,j=y-1;i=0;i+,j-) 一方赢了则改变其颜色if(gridij=color&(y-j=0&j=4&color=1)for (i=x-1,j=y+1;i=0&j=6;i-,j+) 一方赢了则改变其颜色if(gridij=color&(j-y=4&color=2)for (i=x-1,j=y+1;i=0&j=6;i-,j+) 一方赢了则改变其颜色if(gridij=color&(j-y=3)gridij=3;gridxy=3;if(RLWIN

21、-t0=2) gridx+1y-1=3;if(RLWIN-t0=1) gridx+1y-1=3;gridx+2y-2=3;MessageBox(黄赢”);reset();Invalidate();return true;具体判断细节见注释5.reset ()函数设计该函数很简单,即是将数组存储空间归零化。起作用就是让二人对战、人机对战函 数调用,达到初始化数据的目的:for (int i=0;i7;i+)for (int j=0;j =beta)/剪枝;return beta;if (val alpha)/存当前值;alpha = val;returnalpha;/返回当前值;6.2.2关键点

22、与具体设计:alphabeta ()函数设计的关键点包括递归调用、剪枝操作。其中递归的深度由参数 depth限定,剪枝操作跟递归返回的evalue评估函数值息息相关。long CMYSIZIQIView:alphabeta(long alpha,long beta,int d,bool m) int i,j;if(d=0)/the depth of search is enoughreturn evalue();for(i=0;i7;i+) /search for the blankfor(j=0;j7;j+)if(gridij=0) break;if(gridij=0)break;if(i=

23、7&j=7)/no place to movereturn evalue();long a=alpha,b=beta;long current,best;bool first=true,choose=!m; /choose-to decide the layer,max or min int set_color;for(i=0;i=0;j-)/怎 么限制只找一个if(gridij!=0) continue;set_color=(RorY=true&choose=true|RorY=false&choose=false)?1:2;gridij=set_color;memset(sttblack,

24、0,sizeof(sttblack);memset(sttwhite,0,sizeof(sttwhite);Calculate(false,sttblack0,sttblack1,sttblack2,sttblack3,sttblack4,sttblack5,sttbl ack6);/分别计算当前状态Calculate(true,sttwhite0,sttwhite1,sttwhite2,sttwhite3,sttwhite4,sttwhite5,sttwhite6 );current=alphabeta(a,b,d-1,choose);gridij=0;memset(sttblack,0,s

25、izeof(sttblack);memset(sttwhite,0,sizeof(sttwhite);Calculate(false,sttblack0,sttblack1,sttblack2,sttblack3,sttblack4,sttblack5, sttblack6);/分别计算当前状态Calculate(true,sttwhite0,sttwhite1,sttwhite2,sttwhite3,sttwhite4,sttwhite5,sttw hite6);if(first) best=current; first=false;if(d=depth)bestmove0=i;bestmo

26、ve1=j;if(choose)/MAX NODE if(current=b) /beta cut return current;if(bestcurrent)best=current; a=current;if(d=depth)bestmove0=i;bestmove1=j;else/MIN NODEif(currentcurrent)best=current;b=current;if(d=depth)bestmove0=i;bestmove1=j;break;if(d=depth)return 1;return best;7.Calculate ()函数设计7.1该函数主要是统计当前棋局的

27、状态,包括一个棋子一边被堵d1c、一个棋子两 边都没被堵a1c、两个棋子连在一起一边被堵d2c、两个棋子连在一起两边都未堵堵d2c7.2可以从横竖左斜右斜四个方面分析统计 例如横着方向实现如下:/*横有方向 */for (y=6;y=0;y-)for(x=0;x=6;x+)if(gridxy=c)if(x=0)/左 边边界for (i=x+1;i=6;i+)if(gridiy=c) continue;if(gridiy=c0) break;if(gridiy=0)if(i-x=1) d1c+;if(i-x=2) d2c+;if(i-x=3) d3c+;if(i-x=4) d4c+;break;

28、else if(x!=0&x6)/左 右都不是边界for (i=x+1;i2O0?ie(nfi95iwsZiQifflSZiqiuiew.cpp(7e5): error C2oei l::l)riciimFnrG nnrt Snrri nq-nAr1ni ni/ r lj I/ r I I Ui pij .nnnU : f .it.H prrrihError executiog cl.eMB.Creating hraifse imFo File.BSC MAKE: error HKTE06 : cannot open File 1 MebuglWSlIQlUiewsbr- : Ho such

29、File or directoryErr Dr executiirag bsciridk E? aexe atwslzlQl.exe -耳 errcr(s)ff 12 rarninofs)Lew.cpp(149) iew,cpp(1ii9) iew.cpp(149) ieii.cpp(fi09) tru k i-L ir-T u u n -v v* l u k v:earningC4244:1 argumentB:conversionFrom double to intB,二earningC牛24耳二argunent1:ccnversionfrondoubletointB,:uamiriyC4

30、24:argument1:conversionfromBdoubleBtointF,trror C24U7: missing Function Header (oia-style fornal list?|JU _ _M _L BJpO551bpO551bpU551b其中有很多LINK错误是以前没有见过的,就是解决了我也还不知道如何就不再出 错的。总之,只要我每一步写的合情合理错误就不会那么奇怪,倘若稀里糊涂写出来, 出错的可能性将很大。3.2 Calculate()函数的纠结Calculate ()函数的编写与调试整整花了一天的时间,刚开始真的无从下手,连思 路都没有。后来想到自己judge

31、()函数的编写突然有了想法。那就是依然从四个方向 进行统计棋局。但是每一个方向又会有多宗情况:例如横方向,搜索时要分a.连在一起的棋子左端是边界的情况,在a情况下在考虑 其右边是对手棋子还是空位;b.左端右端都不是边界的情况,在b情况下要讨论四种情况;c.右端是边界的情况,在c情况下要讨论左端两种情况。虽然很复杂,但是最难的是第一步,当完成了一个方向的之后其他方向的就迎刃而 解了。alphabeta()和Calculate()函数完成后运行出错(黄色是机器):机器只会从第一列走棋,这显然是alphabeta()函数运行出错,调试分析后发现 错误原因是:在alphabeta()中每假设放完一个棋

32、子也需要统计棋局情况,即也需要 调用Calculate。函数。调用后机器不在放错:.OOOO.OO五、总结与收获通过此次课程设计,我的收获很大。不但对博弈树搜索中alphabeta。剪枝算法掌握 的更加透彻,而且动手编程的能力得到大大提高,尤其是独立编写算法的能力。在此次实践过程中,我遇到了很多的困难,很多次都让我痛苦不堪,但是不管结果是 不是最好,我是自己一步一步实现了我的四子棋游戏。掌握了每一个细节才是我的目的, 掌握统筹思想,掌握发现问题解决问题的处事方式才是我最大的收获。这次动手让我明白,在我们专业领域要勇于挑战,坚信自己一定能够将所学知识运用 到实践。要有恒心和毅力,每一次尝试都可能

33、会遇到困难,但是要坚持到底,走不下去可 以去问人,但是不可以半途而废。我相信这次编程遇到的困难整体的流程将会给我在以后的编程中很大的帮助。对于目 前该程序的缺陷,例如,想绘出几个人性化按钮还没有加上去,评估函数的设计很不合理 导致机器搜索很差,但是有了框架和思路我将会不断完善下去。六、后期展望1. 网络对战二人对战我将会实现网络化,之前已经看过一些网络编程的资料,觉得花时间可以 实现,我自己也期待着亲手实现“我的四子棋”的网络化。2. 优化算法人机对弈算法有待优化,而且每种算法对于不同棋类都会有特例,根据特例进行优化将可能大大节约空间提高效率。七、重要源程序下面贴出害死我很多脑细胞的三个函数源

34、程序清单,但是还得感谢它们让我收获很大:void CMYSIZIQIView:Calculate(bool color,int& d4c,int& a3c,int& d3c,int& a2c,int& d2c,int& a1c,int& d1c)int c=(color=true)?2:1;int c0=(color=true)?1:2;d4c=0;a3c=0;d3c=0;a2c=0;d2c=0;a1c=0;d1c=0int x,y,i,j;/ /kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL kL vt-+=

35、0;y-)for(x=0;x=6;x+)if(gridxy=c)if(x=0)/左 边边界 for (i=x+1;i=6;i+) if(gridiy=c) continue;if(gridiy=c0)break;if(gridiy=0)if(i-x=1) d1c+;if(i-x=2) d2c+;if(i-x=3)d3c+;if(i-x=4)d4c+;break;else if(x!=0&x6)/左 右都不是边界for (i=x+1;i=6;i+)if(gridiy=c) continue;if(gridiy=c0) /右边为对手if(gridx-1y=0)if(i-x=1) d1c+;if(i

36、-x=2) d2c+;if(i-x=3) d3c+;if(i-x=4) d4c+;break;else break;if(gridiy=0)/右 边为 0if(gridx-1y=0)/在 右边为 0 左边为 0if(i-x=1) a1c+;if(i-x=2)a2c+;if(i-x=3)a3c+;if(i-x=4) d4c+;break;else if(gridx-1y=c0)/在 右边为0 左边为对手if(i-x=1) d1c+;if(i-x=2) d2c+;if(i-x=3) d3c+;if(i-x=4) d4c+;break;else if(x=6)if (gridx-1y=c0)break;elsed1c+;break;x=i; rt /* 竖有力向 */for (x=0;x=0;y-)if(gridxy=c)if (y=6)for (j=j-1;j=0;j-)if(gridxj=c) continue;if(gridxj=c0)break;if(gridxj=0)if(y-j=1) d1c+;if(y-j=2) d2c+;if(y-j=3) d3c+;if(y-j=4) d4c+;break;els

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!