游戏人工智能实验报告材料二.docx
《游戏人工智能实验报告材料二.docx》由会员分享,可在线阅读,更多相关《游戏人工智能实验报告材料二.docx(18页珍藏版)》请在冰豆网上搜索。
![游戏人工智能实验报告材料二.docx](https://file1.bdocx.com/fileroot1/2023-1/12/ef4bd584-f7e9-4470-83a1-62455fafa015/ef4bd584-f7e9-4470-83a1-62455fafa0151.gif)
游戏人工智能实验报告材料二
实验二聚集与避障
实验报告
一、实验目的
掌握游戏中聚集与避障的人工智能算法,理解宽视野和有限视野的区别
二、实验仪器
Windows7系统
MicrosoftVisualStudio2015
三、实验原理及过程
//描述聚集与避障的算法原理
//描述程序实现时的思路包括对每个调用的API进行详细说明
智能体只考虑哪些在检测盒内的障碍物。
初始的时候,要将游戏世界中所有的障碍物都迭代到内存中,并标记哪些在检测盒内的障碍物以作进一步分析,然后把所有已经标记的障碍物都转换到智能体的局部空间。
转换坐标后,那些x坐标为负值的物体将不被考虑,所以问题就变得简单多了,接下来必须要检测障碍物是否和检测盒重叠。
使障碍物的包围半径扩大检测盒宽度的一半。
然后测试该障碍物的y值是否小于这个值(即障碍物的包围半径加上检测盒宽度的一半)。
此时,只剩下那些与检测盒相交的障碍物了。
接下来我们找出离智能体最近的相交点。
再一次在局部空间中计算,第三步中扩大了障碍物的包围半径。
用简单的线圆周相交测试方法可以得到被扩大的圈和x轴的相交点。
4、实验结果
五、实验心得(需包括有何不足如何改进)
//你认为目前的聚集与避障有什么不足之处,如何改进
目前的聚集与避障的不足之处在于:
可能会因为错误的方案设计而搞错导致路线的躲闪。
还有就是从实验2开始,我的电脑本身出现了COMCTL32.LIB文件LINK的错误,后来在同学的帮助下我解决了这个问题。
如何改进:
实验前必须要经过精确的计算并且代码不能出现任何错误。
把COMCTL32.LIB文件载入文件以让程序正确运行。
6、主要代码
#include"main.h"
#include"time.h"
//---------------------------------------------------------------------------
/*
Book:
AIforGameDevelopers
Authors:
DavidM.Bourg&GlennSeemann
Example:
Flocking,Chapter4
*/
//---------------------------------------------------------------------------
#define_TIMESTEP0.0025
#define_TOL1e-10
#define_FWDTIME10
#define_THRUSTFACTOR1.0
#define_CHASESETUPtrue
#define_SPAWN_AREA_R100
#define_MAX_NUM_UNITS20
#define_UNIT_LENGTH4
#define_OBSTACLE_RADIUS_FACTOR8
#define_OBSTACLE_RADIUS_OBSTACLE_RADIUS_FACTOR*_UNIT_LENGTH
#define_COLLISION_VISIBILITY_FACTOR25
#define_WIDEVIEW_RADIUS_FACTOR200
#define_NARROWVIEW_RADIUS_FACTOR50
#define_LIMITEDVIEW_RADIUS_FACTOR30
#define_SEPARATION_FACTOR5
#define_BACK_VIEW_ANGLE_FACTOR1
#define_FRONT_VIEW_ANGLE_FACTOR1
#define_NUM_OBSTACLES8
//GlobalVariables:
intFrameCounter=0;
RigidBody2DUnits[_MAX_NUM_UNITS];
VectorTarget;
VectorObstacles[_NUM_OBSTACLES];
boolInitialize(void)
{
inti;
GetRandomNumber(0,_WINWIDTH,true);
for(i=0;i<_MAX_NUM_UNITS;i++)
{
Units[i].fMass=10;
Units[i].fInertia=10;
Units[i].fInertiaInverse=1/10;
Units[i].vPosition.x=GetRandomNumber(_WINWIDTH/2-_SPAWN_AREA_R,_WINWIDTH/2+_SPAWN_AREA_R,false);
Units[i].vPosition.y=GetRandomNumber(_WINHEIGHT/2-_SPAWN_AREA_R,_WINHEIGHT/2+_SPAWN_AREA_R,false);
Units[i].fWidth=_UNIT_LENGTH/2;
Units[i].fLength=_UNIT_LENGTH;
Units[i].fHeight=_UNIT_LENGTH;
Units[i].fOrientation=GetRandomNumber(0,360,false);
Units[i].CD.y=-0.12*Units[i].fLength;Units[i].CD.x=0.0f;//coordinatesofthebodycenterofdrag
Units[i].CT.y=-0.50*Units[i].fLength;Units[i].CT.x=0.0f;//coordinatesofthepropellerthrustvector
Units[i].CPT.y=0.5*Units[i].fLength;Units[i].CPT.x=-0.5*Units[i].fWidth;//coordinatesoftheportbowthruster
Units[i].CST.y=0.5*Units[i].fLength;Units[i].CST.x=0.5*Units[i].fWidth;//coordinatesofthestarboardbowthruster
Units[i].ProjectedArea=(Units[i].fLength+Units[i].fWidth)*Units[i].fHeight;
Units[i].Leader=false;
if(i>_MAX_NUM_UNITS/2)
{
Units[i].Interceptor=true;
Units[i].ThrustForce=_THRUSTFORCE*1.5f;
}else{
Units[i].Interceptor=false;
Units[i].ThrustForce=_THRUSTFORCE;
}
}
for(i=0;i<_NUM_OBSTACLES;i++)
{
Obstacles[i].x=GetRandomNumber(_OBSTACLE_RADIUS*4,_WINWIDTH-_OBSTACLE_RADIUS*4,false);
Obstacles[i].y=/*_WINHEIGHT/2;*/GetRandomNumber(_OBSTACLE_RADIUS*4,_WINHEIGHT-_OBSTACLE_RADIUS*4,false);
}
returntrue;
}
voidDoUnitAI(inti)
{
intj;
intN;
VectorPave;
VectorVave;
VectorFs;
VectorPfs;
Vectord,u,v,w;
doublem;
intNf;
boolInView;
boolDoFlock=WideView||LimitedView||NarrowView;
intRadiusFactor;
//beginFlockAI
Fs.x=Fs.y=Fs.z=0;
Pave.x=Pave.y=Pave.z=0;
Vave.x=Vave.y=Vave.z=0;
N=0;
Pfs.x=0;
Pfs.y=Units[i].fLength/2.0f;
Nf=0;
for(j=1;j<_MAX_NUM_UNITS;j++)
{
if(i!
=j)
{
InView=false;
d=Units[j].vPosition-Units[i].vPosition;
w=VRotate2D(-Units[i].fOrientation,d);
if(((w.y>0)&&(fabs(w.x)if(d.Magnitude()<=(Units[i].fLength*_NARROWVIEW_RADIUS_FACTOR))
Nf++;
if(WideView)
{
InView=((w.y>0)||((w.y<0)&&(fabs(w.x)>fabs(w.y)*_BACK_VIEW_ANGLE_FACTOR)));
RadiusFactor=_WIDEVIEW_RADIUS_FACTOR;
}
if(LimitedView)
{
InView=(w.y>0);
RadiusFactor=_LIMITEDVIEW_RADIUS_FACTOR;
}
if(NarrowView)
{
InView=(((w.y>0)&&(fabs(w.x)RadiusFactor=_NARROWVIEW_RADIUS_FACTOR;
}
if(InView&&(Units[i].Interceptor==Units[j].Interceptor))
{
if(d.Magnitude()<=(Units[i].fLength*RadiusFactor))
{
Pave+=Units[j].vPosition;
Vave+=Units[j].vVelocity;
N++;
}
}
//SeparationRule:
if(InView)//(w.y>0)||((w.y<0)&&(fabs(w.x)>fabs(w.y)*_BACK_VIEW_ANGLE_FACTOR)))
{
if(d.Magnitude()<=(Units[i].fLength*_SEPARATION_FACTOR))
{
if(w.x<0)m=1;
if(w.x>0)m=-1;
Fs.x+=m*_STEERINGFORCE*(Units[i].fLength*_SEPARATION_FACTOR)/d.Magnitude();
}
}
}
}
//CohesionRule:
if(DoFlock&&(N>0))
{
Pave=Pave/N;
v=Units[i].vVelocity;
v.Normalize();
u=Pave-Units[i].vPosition;
u.Normalize();
w=VRotate2D(-Units[i].fOrientation,u);
if(w.x<0)m=-1;
if(w.x>0)m=1;
if(fabs(v*u)<1.0f)
Fs.x+=m*_STEERINGFORCE*acos(v*u)/pi;
}
//AlignmentRule:
if(DoFlock&&(N>0))
{
Vave=Vave/N;
u=Vave;
u.Normalize();
v=Units[i].vVelocity;
v.Normalize();
w=VRotate2D(-Units[i].fOrientation,u);
if(w.x<0)m=-1;
if(w.x>0)m=1;
if(fabs(v*u)<1)
Fs.x+=m*_STEERINGFORCE*acos(v*u)/pi;
}
//Chasethetargetiftheunitisaleader
if(Chase)
{
if(Nf==0)
Units[i].Leader=true;
else
Units[i].Leader=false;
if((Units[i].Leader||!
DoFlock))
{
if(!
Units[i].Interceptor)
{
//Chase
u=Units[0].vPosition;
d=u-Units[i].vPosition;
w=VRotate2D(-Units[i].fOrientation,d);
if(w.x<0)m=-1;
if(w.x>0)m=1;
Fs.x+=m*_STEERINGFORCE;
}else{
//Intercept
Vectors1,s2,s12;
doubletClose;
VectorVr12;
Vr12=Units[0].vVelocity-Units[i].vVelocity;//closingvelocity
s12=Units[0].vPosition-Units[i].vPosition;//rangetoclose
tClose=s12.Magnitude()/Vr12.Magnitude();//timetoclose
s1=Units[0].vPosition+(Units[0].vVelocity*tClose);
Target=s1;
s2=s1-Units[i].vPosition;
w=VRotate2D(-Units[i].fOrientation,s2);
if(w.x<0)m=-1;
if(w.x>0)m=1;
Fs.x+=m*_STEERINGFORCE;
}
}
}
//Collisionavoidance(withstaticobstacles)
Vectora,p,b;
for(j=0;j<_NUM_OBSTACLES;j++)
{
u=Units[i].vVelocity;
u.Normalize();
v=u*_COLLISION_VISIBILITY_FACTOR*Units[i].fLength;
a=Obstacles[j]-Units[i].vPosition;
p=(a*u)*u;
b=p-a;
if((b.Magnitude()<_OBSTACLE_RADIUS)&&(p.Magnitude(){
//impendingcollision...steeraway
w=VRotate2D(-Units[i].fOrientation,a);
w.Normalize();
if(w.x<0)m=1;
if(w.x>0)m=-1;
Fs.x+=m*_STEERINGFORCE*(_COLLISION_VISIBILITY_FACTOR*Units[i].fLength)/a.Magnitude();
}
}
//applyaccumulatedsteeringforce
Units[i].Fa=Fs;
Units[i].Pa=Pfs;
//endFlockAI
}
voidUpdateSimulation(void)
{
doubledt=_TIMESTEP;
inti;
//initializethebackbuffer
if(FrameCounter>=_RENDER_FRAME_COUNT)
{
ClearBackBuffer();
DrawObstacles();
}
//Updateplayercontrolledunit:
Units[0].SetThrusters(false,false,1);
Units[0].SetThrusters(false,false,1);
if(IsKeyDown(VK_RIGHT))
Units[0].SetThrusters(true,false,0.5);
if(IsKeyDown(VK_LEFT))
Units[0].SetThrusters(false,true,0.5);
Units[0].UpdateBodyEuler(dt);
if(FrameCounter>=_RENDER_FRAME_COUNT)
DrawCraft(Units[0],RGB(0,255,0));
if(Units[0].vPosition.x>_WINWIDTH)Units[0].vPosition.x=0;
if(Units[0].vPosition.x<0)Units[0].vPosition.x=_WINWIDTH;
if(Units[0].vPosition.y>_WINHEIGHT)Units[0].vPosition.y=0;
if(Units[0].vPosition.y<0)Units[0].vPosition.y=_WINHEIGHT;
//updatecomputercontrolledunits:
for(i=1;i<_MAX_NUM_UNITS;i++)
{
DoUnitAI(i);
Units[i].UpdateBodyEuler(dt);
if(FrameCounter>=_RENDER_FRAME_COUNT)
{
if(Units[i].Leader)
DrawCraft(Units[i],RGB(255,0,0));
else{
if(Units[i].Interceptor)
DrawCraft(Units[i],RGB(255,0,255));
else
DrawCraft(Units[i],RGB(0,0,255));
}
}
if(Units[i].vPosition.x>_WINWIDTH)Units[i].vPosition.x=0;
if(Units[i].vPosition.x<0)Units[i].vPosition.x=_WINWIDTH;
if(Units[i].vPosition.y>_WINHEIGHT)Units[i].vPosition.y=0;
if(Units[i].vPosition.y<0)Units[i].vPosition.y=_WINHEIGHT;
}//endi-loop
if(FrameCounter>=_RENDER_FRAME_COUNT){
CopyBackBufferToWindow();
FrameCounter=0;
}else
FrameCounter++;
}
voidDrawCraft(RigidBody2Dcraft,COLORREFclr)
{
VectorvList[5];
doublewd,lg;
inti;
Vectorv1;
wd=craft.fWidth;
lg=craft.fLength;
vList[0].y=lg/2;vList[0].x=wd/2;
vList[1].y=-lg/2;vList[1].x=wd/2;
vList[2].y=-lg/2;vList[2].x=-wd/2;
vList[3].y=lg/2;vList[3].x=-wd/2;
vList[4].y=lg/2*1.5;vList[4].x=0;
for(i=0;i<5;i++)
{
v1=VRotate2D(craft.fOrientation,vList[i]);
vList[i]=v1+craft.vPosition;
}
DrawLine(vLi