人工智能与专家系统Word格式文档下载.docx
- 文档编号:19060339
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:37
- 大小:529.32KB
人工智能与专家系统Word格式文档下载.docx
《人工智能与专家系统Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《人工智能与专家系统Word格式文档下载.docx(37页珍藏版)》请在冰豆网上搜索。
如前面有路时就往前走,前面的路走过就往没走过的地方走等。
这些法则必须确实可以让物体搜索迷宫中的每一块区域来找到出口,若走迷宫的法则设定得
不完整,那么物体就有可能在同一个地方兜圈子,永远找不到出口了。
此外,为了让物体在走出迷宫后能知道正确走出迷宫的路径,必须给物体一张地图来记
录所走过的路径,这张图就是一个链表结构,当物体成功走出迷宫后,整个链表就是正确走出迷宫的路径。
如图1所示
L-Il口
□绘関也口
FFFFFFFF
图1
图1中,实线部分为小球走迷宫的最短路径,依照走迷宫的规则每移动到新一格时,该
区域就被增加到链表中,而当走过的区域并非正确路径时(图中虚线部分),则从链表中删
除。
例如:
上图中虚线部分为小球所走过的区域,但小球进入该区域后发现是死路,因此必
须倒退,每倒退一格时,就表示该格不是正确路径,因此从链表中删除;
最后,当小球走出迷宫后,正确路径便会记录在链表中。
搜寻最佳路径
在这个迷宫路径搜寻的程序中,我以一颗小球来走迷宫,小球会自动搜寻到迷宫的入口,
接着自动找寻出口,当找到出口后便记录着正确走出迷宫的路径,按[F2]键察看此最短路径。
定义迷宫的方式
使用一个整数的二维数组
maze[8][8]来存储整个迷宫的状态。
如图2
3,入口的元素值为2,墙元素值为1,通道的元素值
maze[0][1],同时,以变量m,n分别代表数组一维与
出口
定义数组时,设定出口元素值为为0。
图2中,代表入口的数组元素为二维的索引值,具体如下所示:
maze[m][n]=3
//
maze[m][n]=2
入口
maze[m][n]=1
墙
maze[m][n]=0
通道
双向链表的使用
在程序中我使用双向链表记录小球所走过的路径,结构定义如下:
structlist//定义链表结构
{
图中,虚线部分是小球所走过的错误路径,在走进错误区域后,都是死路。
因此小球必须沿原先进入的路径后退。
在后退后,原先加到链表中的错误结点也会同时从链表中删除,而后退到有其他未走过的格子可以走时,就往那一个格子前进,最后找到出口后,正确的行进路线的结点便记录在链表中。
走迷宫的规则
先试着往下走,若下一格有墙或者走过,则试着往右走
若右一格有墙或者走过,则试着往左走
若左一格有墙或者走过,则试着往上走
若上一个有墙或者走过,此时表示上、下、左、右都有未走过的格,便必须往后退,回到上一结点位置并删除目前结点
以下列出依各条规则所设定出的算法:
1)
试图往下走的程序代码:
if(下一格是墙)
/*试图往右走的程序代码*/
else
if(下一格走过)
/*试图往右走的程序代码
//往下走并新增结点
*/
2)
试图往右走的程序代码:
if(右一格是墙)
/*试图往左走的程序代码*/
if(右一格走过)
/*试图往左走的程序代码
//往右走并新增结点
3)
试图往左走的程序代码:
if(左一格是墙)
/*试图往上走的程序代码*/
if(左一格走过)
/*试图往上走的程序代码
//往左走并新增结点
4)
试图往上走的程序代码:
if(上一格是墙)
//回上一个结点并删除目前结点
if(上一格走过)
//往上走并新增结点
将上面4组算法结合起来,就得到整个走迷宫的判断式结构了
程序内容说明:
本迷宫游戏的主要功能如下:
程序执行式自动搜寻入口与出口按[F1]键可重新进行搜寻
按[F2]键辉县是正确走迷宫的路径
若迷宫无出口,则搜寻结果会显示无出口的信息
intmaze[8][8]=
{1,1,1,1,1,1,1,120,0,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,1,1,0,1,0,1,0,0,1,131,1,1,1,1,1};
BOOLpass[8][8];
inti,j,m,n,lastm,lastn;
BOOLstart=true,search=true,go;
pointerptr,preptr,first;
charstr[10];
canvasFrame:
:
canvasFrame()
/*建立窗口与加载图文件的程序代码
for(i=0;
i<
7;
i++)
for(j=0;
j<
j++)if(maze[i][j]==2)break;
if(maze[i][j]==2)
break;
}m=i;
n=j;
ptr=(pointer)malloc(sizeof(node));
ptr->
m=m;
n=n;
ptr->
next=NULL;
ptr->
back=NULL;
first=ptr;
}
说明:
第3---10行程序代码为一个双层循环,用来搜寻二位数组中,元素值为2的元素;
第
6---8行程序代码判断若找到了此元素,则结束循环,此时I与j的值便是代表迷宫入口
的索引值
第11、12行程序代码将i,j的值赋予给m、n,这是第一个链表结点中所要存储的值第13行程序代码建立第一个节点的指针ptr,接着14、15行程序代码设定其中的成员
变量m与n的值,第16、17行程序代码则将结点的前后指针指向NULL。
如此,第一
个结点结构如下:
m
n
back
next
其中结点的back指针是用以指向链表中的上一个结点,next指针则是指向下一个结点,
如此便形成双向链表,而小球在走迷宫时才能够前进与后退
4)第18行程序代码则设定first等于ptr,用来记录链表第一个结点的位置
voidcanvasFrame:
OnTimer(UINTnIDEvent){
if(start)
Start();
//开始搜寻
if(search)
Search。
;
if(go)
Go();
//进行搜寻
//显示最短路径
CFrameWnd:
OnTimer(nIDEvent);
在OnTimer函数中则是会依目前程序的状况来执行开始搜寻,显示最短路径等于自定义函数。
Start函数,将小球的图案显示于入口上。
会执行Search函数,而当用户按下[F2]键时,则会
程序于一开始进行搜寻时便会执行
接下来每次进行搜寻而小球移动时,调用Go函数来显示走出迷宫最短路径
Start()
CClientDCdc(this);
mdc->
SelectObject(tile);
=7;
j++)
if(maze[i][j]==1)
dc.BitBlt(j*40,i*40,40,40,mdc,0,0,SRCCOPY);
SelectObject(ball);
dc.BitBlt(ptr->
n*40,ptr->
m*40,40,40,mdc,0,0,SRCCOPY);
start=false;
lastn=ptr->
n;
lastm=ptr->
m;
在start函数中,第4---8行程序代码会先贴上迷宫中的墙。
使用双层循环在条件式maze[i][j]==1成立时,则以左上角的贴图坐标(j*40,i*40,)来进行贴上墙的动作
第10行程序代码则以ptr所指结点中m与n成员变量的值来计算贴图坐标,此时ptr所指结点为第一个结点,因此贴图后,小球会出现在迷宫入口位置上
接下来第11行程序代码将start变量设定为false,第12、13行程序代码则将结点m与
n的值记录在lastm与lastn中,以便下次执行OnTimer时可以覆盖掉前一次的贴图voidcanvasFrame:
Search()
mdc->
dc.BitBlt(j*40,i*40,40,40,mdc,0,0,SRCCOPY);
if(maze[m+1][n]==1)//下一格是墙
/*判断行进方向与变更链表内容的程序代码
if(pass[m+1][n])//下一格走过
if(maze[m][n+1]==1)〃右一格是墙
if(maze[m][n-1]==1)//左一格是墙
if(maze[m-1][n]==1)//上一格是墙
if(ptr->
back!
=NULL)
ptr=ptr->
back;
free(ptr->
next);
next=NULL;
m=ptr->
n=ptr->
}else
if(pass[m-1][n])
〃上一格走过
next=NULL;
n=ptr->
m-=1;
//往上一格
next=(pointer)malloc(sizeof(node));
ptr->
next->
preptr=ptr;
pass[m][n]=true;
ptr=ptr->
next;
back=preptr;
m+=1;
//往下一格
next=(pointer)malloc(sizeof(node));
next->
preptr=ptr;
dc.BitBlt(lastn*40,lastm*40,40,40,mdc,0,0,WHITENESS);
dc.BitBlt(ptr->
m*40,40,40,mdc,0,0,SRCCOPY);
if(ptr->
back==NULL)
dc.TextOut(120,320,"
找不到出口”);
search=false;
if(maze[m][n]==3)
找到出口”);
ptr
25行程序代码则依目前ptr所指的结点来重设m与n的值
第24、
7)当有未走过的格子可走时,此时就必须在链表的最后加上代表新格子的结点,如第40---51行与第53---64行的程序代码
8)以第40---51行往上一动一格的程序代码为例,我们来说明加入新结点的方式,第行程序代码将m值减1代表上一个格子,而新增结点的过程则如底下的图标所示。
42
执行第43行程序代码:
新结点
1
■
NULLNULL
1n
执行第44、45行程序代码:
mnbackInext
执行第46行程序代码:
nbacknext
ptrpreptr
执行第47行程序代码:
执行第49行程序代码:
执行第50行程序代码:
11)
9)
第67行程序代码判断小球是否会到第一个结点,便表示这个迷宫没有出口,而第一个结点的back指针指向NULL,因此69行程序代码显示找不到出口的信息,并将Search
设为false。
在每次计算m与n值之后,若maze[m][n]元素值为3,则表示小球移动到了定义为出口的地方,第72行判断式成立,接下来便显示找到出口的信息,同时将Search设定为false。
Go()
dc.BitBlt(n*40,m*40,40,40,mdc,0,0,SRCCOPY);
最短路径”);
go=false;
当用户按下[F2]键后便会将go变量设定为true,并将链表的指针移回第一个结点。
OnTimer函数中就会不断地调用Go函数来进行小球贴图显示正确走出迷宫的路径:
第4、5行程序代码取出目前结点m与n的值
第7---10行程序代码贴上迷宫中的墙
第12行程序代码依m与n的值贴上小球图
第13行判断式判断maze[m][n]是否等于3,若等于3则表示已走到了出口,显示最短路径的信息,并将go设定为false;
否则第19行程序代码将指针移到链表的下一个结点,已进行下一次小球的移动
OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags){
if(nChar==VK_ESCAPE)
PostMessage(WM_CLOSE);
if(nChar==VK_F1)
start=true;
search=true;
go=false;
=8;
i++)//清空数组
Pass[i][j]=false;
m*40,40,40,mdc,0,0,WHITENESS);
while(ptr->
back)〃删除结点
free(ptr->
n=ptr->
if(nChar==VK_F2)
此迷宫无出口”);
//移动指针到第一个结点
ptr=first;
go=true;
OnKeyDown(nChar,nRepCnt,nFlags);
OnKeyDown函数用于处理按下按键信息,用户可按下[ESC]键来结束程序,按[F1]键重新进
行搜寻,按[F2]键显示走出迷宫的路径。
5)
6)
7)
8)
第7行程序代码判断若用户按下[F1]键,则将start、search变量设定为true,go变量设
定为false,如此OnTimer函数会调用Start与Search函数重新进行路径搜寻
第12---14行程序代码将记录走过格子的二维数组中的各元素重新设定为false
第15行程序代码覆盖最后一次的小球贴图
第16---21行得while循环进行链表结点的删除,仅留下第一个开始的结点
第22、23行程序代码设定变量m与n的值为第一个结点的成员变量m与n的值,即
为小球已开始所在的格子
若用户按下了[F2]键,此时程序必须将链表指针的位置移到第一个结点,然后再一一取出各个结点中的m与n的值,来贴上小球图以显示路径
第27行判断式中的条件式ptrback==NULL若成立则所在结点为第一个结点(入口结
点),即表示迷宫没有出口
若ptrback==NULL不成立,则31行程序代码将链表的指针移动到第一个结点的位置上,然后将go设定为ture,search设定为false,以执行显示最佳路经得Go函数
找到出口
箱国宙U
2"
最短路径当迷宫设定为无出口时,则搜寻后结果如下图所示:
可以通过改变数组中的数据来改变迷宫路径,
找不到出口
程序也可自动找到入口并搜寻走出迷宫的路径
5年前,当得知象棋大师卡斯帕罗夫同IBM“深蓝二代”计算机的对弈以失败告终后,人
工智能,在我的脑海里便成为了一个神秘并且深不可及的名词。
在我看来,它可以让很多本
会与人
来没有思想的东西变得富有生命力,赋予他们思考的能力。
比如会踢足球的机器人,
对弈的计算机,可以自动控制的家电等等。
虽然迷
这个学期,通过人工智能与专家系统这门课程的学习,使我对人工智能这个前沿领域有了初步的了解。
当得知要进行课程设计的时候,我的心里是欣喜并且有些担忧的。
宫游戏只是属于人工智能的一个小小的分支,但是,要完成这样的课程设计对我来说还是有
相当大的难度的。
为此,我查阅了很多计算机游戏编程的书籍,并且到网上搜集了很多的资
料,为这次编程进行了很充足的准备。
然而,理论转变为实际的过程中,还是存在着许多大
大小小的问题的。
首先,在分析问题的时候,应该要尽可能的全面。
迷宫游戏中,涉及路径搜寻时必须
设定物体的一些走出迷宫的法则。
如前面有路时就往前走,前面的路走过就往没走过的地方
走等。
这些法则必须确实可以让物体搜索迷宫中的每一块区域来找到出口,若走迷宫的法则
设定得不完整,那么物体就有可能在同一个地方兜圈子,永远找不到出口了。
写程序对我来说确实是件有点头疼的事情。
起初设想的算法写着写着发现原来是行不通的。
这时,就需要及时的更正,一条路走不同,就要从另外的角度去思考问题了。
在程序调试的过程中一份平和的心态以及冷静的头脑尤为重要,不能急躁,往往漏洞就出现在最不
起眼的地方。
只有冷静下来,心思缜密的从头把程序梳理下来,细心思考每一个步骤,每
个过程,通过逐步调试,才能一点点地将错误纠正过来。
在通过自己的一番辛苦努力以及同学的指导之下,当最终调试出了另人满意的结果的时候,心里那种成功的喜悦感是无法言表的。
人工智能是一个很深奥的领域。
通过这次的课程设计,初步激发了我对这个领域的兴趣。
相信在以后的学习以及工作过程当中,我一定会尝试着去接触更多更深层次的方面,
望有朝一日,我也可以为人工智能这个领域做出一些贡献。
C++动画编程
参考书
水力水电出版社
电子工业出版社
C++游戏动感编程
人工智能基础编程
西北电子科技大学出版社
//canvasFrame.cpp:
impiementationfile
#include"
stdafx.h"
#include"
canvasr.h"
canvasFrame.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHISFILE
staticcharTHIS_FILE[]=_FILE.
#endif
structlist
//定义链表结构
intm;
intn;
structlist*next;
structlist*back;
//指向下一个结点
//指向前一个结点
};
typedefstructlistnode;
typedefnode*pointer;
//定义结点
//定义动态指针
////////////////////////////////////////////////////////////////////////////
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 人工智能 专家系统