百度之星坦克大战代码.docx
《百度之星坦克大战代码.docx》由会员分享,可在线阅读,更多相关《百度之星坦克大战代码.docx(16页珍藏版)》请在冰豆网上搜索。
![百度之星坦克大战代码.docx](https://file1.bdocx.com/fileroot1/2023-4/1/4b3c04c8-3f49-4ce3-8111-ca5d35d5bb93/4b3c04c8-3f49-4ce3-8111-ca5d35d5bb931.gif)
XX之星坦克大战代码
#include"Tank.h"
#include
#include"main.cpp"
//请勿修改以上头文件
/*您可以在这里添加您所需头文件*/
#include"stdio.h"
#include
#include
usingnamespacestd;
/*您可以在这里添加您的自定义函数*/
/*A*寻路算法*/
//所需结构定义
typedefstructnode//aStar算法需要的动态表节点
{
intid;
intfather;//父节点编号
intcost;//从初始位置到达此次的花费g(x)
}node;
staticvectoropenT;//open表
staticvectorclosedT;//closed表
staticvectorpath[MAX_TANK_NUM];//路径存储位置
staticsettargeted;//标记目标矿点是否被己方锁定,存在则锁定
intpoint2id(introw,intcol)//节点编号
{
intid=row*(MAP_WIDTH+2)+col;
returnid;
}
Pointid2point(intid)//节点反编号
{
Pointpo;
po.row=id/(MAP_WIDTH+2);
po.col=id%(MAP_WIDTH+2);
returnpo;
}
//查找某vector表中是否有一节点
intfind(intid,vectorvet)
{
if(vet.empty())
{
return-1;
}
for(inti=0;i{
if(id==vet[i].id)
{
returni;
}
}
return-1;
}
//查找当然位置在path[myID]中的index
intfindPathIdx(intid,vectorpathT)
{
if(pathT.empty())
{
return-1;
}
for(inti=0;i{
if(id==pathT[i])
{
returni;
}
}
return-1;
}
//返回从一节点到邻近节点的花费(坦克要走的步数)
//可通过PERVIOUS为1,BRICK为2,BREAKBRICK为3
intaddcost(CellTypetype)
{
switch(type){
casePERVIOUS:
return1;
break;
caseBRICK:
return2;
break;
default:
return3;
}
}
//对给定扩展点进行检测添加
voidaddExtNode(nodetmpNode,intextid,CellTypetype)
{
PointextPo;
nodeextNode;
extPo=id2point(extid);
if((-1==find(extid,closedT))&&(STONE!
=type))//要扩展点不在closed表中,且不为石头则扩展
{
intidx=find(extid,openT);//在open表中的索引
if(-1==idx)//如果不在open表中则添加
{
extNode.id=extid;
extNode.father=tmpNode.id;
extNode.cost=tmpNode.cost+addcost(type);
openT.push_back(extNode);
}
else//如果在open表中,看新路径是否更近,近则修改
{
if(tmpNode.cost+addcost(type){
openT[idx].father=tmpNode.id;
openT[idx].cost=tmpNode.cost+addcost(type);
}
}
}
}
//得到本坦克的路径
voidgetPath(intmyID,intgoalIdx)
{
//id为myID的坦克路径存于path[myID]中
path[myID].clear();
nodetmpNode=openT[goalIdx];
path[myID].insert(path[myID].begin(),tmpNode.id);
/*
Pointdebug_po=id2point(tmpNode.id);
printf("PathStar!
\nGoal(%d,%d)\n",debug_po.row,debug_po.col);
*/
while(-1!
=tmpNode.father)
{
inttmpIdx=find(tmpNode.father,closedT);
//printf("%d",tmpIdx);
if(-1!
=tmpIdx)
{
tmpNode=closedT[tmpIdx];
/*
Pointdebug_po=id2point(tmpNode.id);
printf("(%d,%d)\n",debug_po.row,debug_po.col);
*/
path[myID].insert(path[myID].begin(),tmpNode.id);
}
else
{
path[myID].clear();
return;
}
}
}
//根据下一步目标返回:
方向运动指令
OrderTypegetOrder(FlagTypemyFlag,PointmySite,PointnextStep)
{
introwD=nextStep.row-mySite.row;
printf("%d",rowD);
intcolD=nextStep.col-mySite.col;
printf("%d",colD);
switch(rowD)
{
case-1:
returnGOUP;
break;
case1:
returnGODOWN;
break;
default:
;
}
switch(colD)
{
case-1:
returnGOLEFT;
break;
case1:
returnGORIGHT;
break;
default:
;
}
returnSTOP;
}
//A*寻路算法,路径存储在path[myID]中
voidaStar(intmyID,Pointstart,Pointgoal,MapCellmap[][MAP_WIDTH+2])
{
openT.clear();
closedT.clear();
path[myID].clear();
//1.把初始节点放入openT
nodetmpNode;
tmpNode.id=point2id(start.row,start.col);
tmpNode.father=-1;//初始节点无父节点
tmpNode.cost=0;
openT.push_back(tmpNode);
//2.如果openT为空,搜索失败退出
boolfindGoal=false;
while(!
openT.empty()&&!
findGoal)
{
tmpNode=openT[0];
intno=0;//记录最小f(x)的索引
//3.移除openT中f(x)值最小的
Pointp1=id2point(tmpNode.id);//当前考察点位置
inthx1=abs(goal.row-p1.row)+abs(goal.col-p1.col);//当前路径cost
intfx1=hx1+tmpNode.cost;
//寻找f(x)最小的节点
for(inti=0;i{
nodetmpNode2=openT[i];
Pointp2=id2point(tmpNode2.id);
inthx2=abs(goal.row-p2.row)+abs(goal.col-p2.col);
intfx2=hx2+tmpNode2.cost;
if(fx1>fx2)
{
tmpNode=openT[i];
no=i;
}
}
//如果节点为目标节点,则路径找到,返回路径
if(point2id(goal.row,goal.col)==tmpNode.id)
{
//存储路径
getPath(myID,no);//当目标在open中,得到的最小f(x)的点是目标节点索引为no
return;
}
//从openT移节点如closedT中
openT.erase(openT.begin()+no);
closedT.push_back(tmpNode);
//4.从四个方向扩展节点
PointtmpPo;
tmpPo=id2point(tmpNode.id);
intextid;
CellTypetype;
//上
extid=point2id(tmpPo.row-1,tmpPo.col);
type=(map[tmpPo.row-1][tmpPo.col]).type;
addExtNode(tmpNode,extid,type);
//下
extid=point2id(tmpPo.row+1,tmpPo.col);
type=(map[tmpPo.row+1][tmpPo.col]).type;
addExtNode(tmpNode,extid,type);
//左
extid=point2id(tmpPo.row,tmpPo.col-1);
type=(map[tmpPo.row][tmpPo.col-1]).type;
addExtNode(tmpNode,extid,type);
//右
extid=point2id(tmpPo.row,tmpPo.col+1);
type=(map[tmpPo.row][tmpPo.col+1]).type;
addExtNode(tmpNode,extid,type);
}
}
//平台0回合时调用此函数获取AI名称及坦克类型信息,请勿修改此函数声明。
extern"C"InitiateInfochooseType()
{
InitiateInfoInfo;
Info.tank[0]=Pioneer;
Info.tank[1]=Sniper;
Info.tank[2]=Pioneer;
Info.tank[3]=Sniper;
Info.tank[4]=Pioneer;
strcpy(Info.aiName,"AISeminar_cn");//AI名请勿使用中文。
targeted.clear();
returnInfo;
}
//平台从第1回合开始调用此函数获得每回合指令,请勿修改此函数声明。
extern"C"OrdermakeOrder(DataForAIdata)
{
Orderorder;
PointmySite;
//获得当前坦克位置
intmyID=data.myID;
inttankType=data.tank[myID].type;
//获得自己的坐标点
mySite.row=data.tank[myID].row;
mySite.col=data.tank[myID].col;
//获得自己的资源类型
intmySrcType;
switch(data.myFlag)
{
caseRED:
mySrcType=RedSource;
break;
caseBLUE:
mySrcType=BlueSource;
break;
}
//获得自己的射程
intactDist;
switch(tankType)
{
caseSniper:
actDist=5;
break;
caseStriker:
actDist=3;
break;
default:
actDist=1;
}
//获取敌方坦克位置信息(行列的第0、MAP_WIDTH+1处为墙)
//如果,在攻击范围内,则攻击
for(intmCol=1;mCol{
for(intmRow=1;mRow{
inttankIdx=data.map[mRow][mCol].whoIsHere;
if(tankIdx!
=-1&&data.tank[tankIdx].flag!
=data.myFlag)
{
inttankDist=abs(data.tank[tankIdx].row-mySite.row)+abs(data.tank[tankIdx].col-mySite.col);
if(tankDist<=actDist)
{
order.type=FIRE;
order.row=mRow;
order.col=mCol;
returnorder;
}
}
}
}
//不进行攻击时,获取矿点信息
//命令构造:
如果攻击范围内有坦克,先攻击,在寻路
intidx=findPathIdx(point2id(mySite.row,mySite.col),path[myID]);
boolneedPath=false;
if(path[myID].empty())//不在存储路径中
{
needPath=true;
}
else
{
intendIdx=path[myID].size()-1;
PointendPo=id2point(path[myID][endIdx]);
//查找目标是否已经是己方占领
if((-1==idx)||(endIdx==idx)||((data.map[endPo.row][endPo.col]).isHereSource==mySrcType))
{
targeted.erase(point2id(endPo.row,endPo.col));
needPath=true;
}
}
//当前位置不存在路径中,或已经达到目标、或目标点已经是己方则重新计算路径
while(needPath||(-1==idx))
{
//获得离自己最近的非己方矿点位置
PointgoalSite;//目标坐标点
goalSite.row=data.source[0].row;//防止目标全部被锁定,无目标时传递给astar的数据出错
goalSite.col=data.source[0].col;
intmy2srcDist=MAP_WIDTH*MAP_WIDTH+MAP_HEIGHT*MAP_HEIGHT;//记录与最近非己方资源的距离(直线距离平方,“行距+列距”效果不好,初始最大)
//寻找“距离本坦克最近”的非己方矿点(**且“自己在己方中也是最近”)
for(inti=0;i{
inttempSR=data.source[i].row;
inttempSC=data.source[i].col;
intsrcID=point2id(tempSR,tempSC);
//在矿点非己方时,且矿点未被己方坦克锁定时(锁定表中不存在),规划路径
if(((data.map[tempSR][tempSC]).isHereSource!
=mySrcType)&&(targeted.find(srcID)==targeted.end()))
{
//inttempDist=abs(tempSR-mySite.row)+abs(tempSC-mySite.col);
inttempDist=(tempSR-mySite.row)*(tempSR-mySite.row)+(tempSC-mySite.col)*(tempSC-mySite.col);
if(tempDist{
my2srcDist=tempDist;
goalSite.row=tempSR;
goalSite.col=tempSC;
}
}
}
//如果目标未被锁定则加入锁定表,如果已锁定,说明无满足条件者
if(targeted.find(point2id(goalSite.row,goalSite.col))==targeted.end())
{
targeted.insert(point2id(goalSite.row,goalSite.col));
}
printf("Tand%d-Goal:
(%d,%d)\n",myID,goalSite.row,goalSite.col);//debug!
//A*寻路
aStar(myID,mySite,goalSite,&(data.map[0]));
needPath=false;
//*显示路径debug
for(intpi=0;pi{
Pointdebug_po=id2point(path[0][pi]);
printf("(%d,%d)\n",debug_po.row,debug_po.col);
}
//*/
//寻找当前位置在path中的索引
idx=findPathIdx(point2id(mySite.row,mySite.col),path[myID]);
}
//路径判断后进行命令处理
PointnextStep=id2point(path[myID][idx+1]);
if(PERVIOUS!
=(data.map[nextStep.row][nextStep.col]).type)//如果路径不是可通过的,则轰炸
{
order.type=FIRE;
order.row=nextStep.row;
order.col=nextStep.col;
}
else
{
order.type=getOrder(data.myFlag,mySite,nextStep);
}
returnorder;
}