#include "Tank.h" #include <string.h> #include <stdlib.h> #include <time.h> #include <queue> #include <cassert> #define CLOCKS_PER_SEC ((clock_t)1000) clock_t start,finish; //请勿修改以上头文件 /* 您可以在这里添加您所需头文件 */ /* 您可以在这里添加您的自定义函数 */ //平台0回合时调用此函数获取AI名称及坦克类型信息,请勿修改此函数声明。 #include<iostream> #define INF 500000 #define MY 450 using namespace std; int d[100][100],tankID[10],PtankID[10]; int nearest_friend[10],Pnearest_friend[10]; int match[20],ans_match[20],ans,Pans,Pans_match[20],Pmatch[20]; int get_hurt[23][23],make_hurt[23][23]; int dd[23][23][23][23]; int stop[11]; bool is_added[30]; Point Fire_at[20]; int tot_Fire; bool no_way_out[23][23]; bool used[20],Pused[20]; bool visited[23][23]; bool is_see[23][23]; int weight[23][23]; struct direction { int x,y; OrderType type; }; struct pt { int x,y,dist; bool operator <(const pt &rhs) const { if (dist>rhs.dist) return true; else return false; } }; direction dir[7]; Order tp[5]; int sc_aimed[30]; int tp_now,sc_num,Psc_num; int dist[20][20],l,Pdist[20][20]; DataForAI dt,predt,dt_now,temp_dt; //GOUP,GODOWN,GOLEFT,GORIGHT extern "C" InitiateInfo chooseType() { int i; dir[0].x=-1;dir[0].y=0;dir[0].type=GOUP; dir[1].x=1;dir[1].y=0;dir[1].type=GODOWN; dir[2].x=0;dir[2].y=-1;dir[2].type=GOLEFT; dir[3].x=0;dir[3].y=1;dir[3].type=GORIGHT; dir[4].x=0;dir[4].y=0;dir[4].type=STOP; InitiateInfo Info; memset(dd,-1,sizeof(dd)); Info.tank[0]=Sniper; Info.tank[1]=Sniper; Info.tank[2]=Sniper; Info.tank[3]=Sniper; Info.tank[4]=Sniper;//Striker Sniper Pioneer srand(time(NULL)); for(i=0;i<10;i++ ) stop[i]=0; tp_now=0;l=5; strcpy(Info.aiName,"SwordHoly's AI_3"); //AI名请勿使用中文。 return Info; } //平台从第1回合开始调用此函数获得每回合指令,请勿修改此函数声明。 int min(int x,int y) { if (x<y) return x; else return y; } bool in_map(int x,int y) { if ( (x>=1)&&(x<=21)&&(y>=1)&&(y<=21) ) return true; else return false; } bool can_walk(int x,int y) { if (dt.map[x][y].type==0) return true; else return false; } Point is_attack(int tankID) { TankData myTank=dt.tank[tankID]; int i,j,hp=INF; Point res; res.row=-1; Point now; now.row=myTank.row; now.col=myTank.col; for(i=-myTank.range;i<=myTank.range;i++) for(j=-myTank.range;j<=myTank.range;j++) if (abs(i)+abs(j)<=myTank.range) { if (in_map(now.row-i,now.col-j)) if (dt.map[now.row-i][now.col-j].whoIsHere!=-1) { int whoIsHere=dt.map[now.row-i][now.col-j].whoIsHere; if ((dt.tank[whoIsHere].flag!=myTank.flag)&&(dt.tank[whoIsHere].life<hp) ) { hp=dt.tank[whoIsHere].life; res.row=now.row-i; res.col=now.col-j; } } } return res; } int calc(int x,int y) { if (!(in_map(x,y))) return INF; if (dt.map[x][y].type==PERVIOUS) return 1; if (dt.map[x][y].type==BREAKBRICK) return 2; if (dt.map[x][y].type==BRICK) return 3; else return 1; } struct que { int s,t; pt a[23*23*23*23*23]; void init(){s=1;t=0;} pt top(){return a[s];} pt pop(){return a[s++];} void push(pt p){a[++t]=p;} bool empty() { if (s>t) return true; else return false; } }; que q; int dis(int sx,int sy,int tx,int ty) { int i,j,min_d,min_x,min_y,xx,yy; //priority_queue<pt> q; // cout<<sx<<' '<<sy<<' '<<tx<<' '<<ty<<' '<<endl; for(i=1;i<=21;i++) for(j=1;j<=21;j++) { d[i][j]=INF; visited[i][j]=false; } //memset(visited,false,sizeof(visited)); pt temp,now,next; temp.x=sx;temp.y=sy;temp.dist=0; d[sx][sy]=0; //while(!q.empty()) q.pop(); q.init(); q.push(temp); while( (!visited[tx][ty])&&(!q.empty()) ) { now=q.top(); q.pop(); if (visited[now.x][now.y]) continue; min_d=now.dist; min_x=now.x; min_y=now.y; if (min_d<INF) { d[min_x][min_y]=min_d; visited[min_x][min_y]=true; for(i=0;i<4;i++) { xx=min_x+dir[i].x; yy=min_y+dir[i].y; if ( (in_map(xx,yy))&&(dt.map[xx][yy].type!=STONE) ) { next.x=xx;next.y=yy; next.dist=d[min_x][min_y]+calc(xx,yy); q.push(next); } } } else return INF; } // assert(d[tx][ty]<INF); return d[tx][ty]; } bool source_more(int id)//判断是否需要占领更多的矿 { int i,j,tot; tot=0; Point now; now.row=dt.tank[id].row; now.col=dt.tank[id].col; for(i=-6;i<=6;i++) for(j=-6;j<=6;j++) if (abs(i)+abs(j)==6) if ( in_map(now.row+i,now.col+j) ) if (dt.map[now.row+i][now.col+j].whoIsHere!=-1) if ( (dt.tank[dt.map[now.row+i][now.col+j].whoIsHere].flag!=dt.myFlag)&&(dt.tank[dt.map[now.row+i][now.col+j].whoIsHere].type==Sniper)) { tot++; } if (tot>=2) return false; if (dt.myFlag==BLUE) { if ( ((1000-dt.redGoldNum)*dt.blueSource)<=((1000-dt.blueGoldNum)*dt.redSource) ) return true; else return false; } else { if ( ((1000-dt.blueGoldNum)*dt.redSource)<=((1000-dt.redGoldNum)*dt.blueSource) )return true; else return false; } } Order walk_to_sc(Point now,int min_sc,int tankID) { int min_dd,min_ord,xx,yy,shft,i,t,min_shft,x; Order order; order.type=STOP; if ((now.row==dt.source[min_sc].row)&&(now.col==dt.source[min_sc].col) ) return order; //return order; int RP=rand()%2; min_dd=INF; min_ord=0; x=5; if ((stop[tankID]>=3)&&(source_more(tankID))) {x=4;} if (RP==0) for(i=0;i<x;i++) { xx=now.row+dir[i].x; yy=now.col+dir[i].y; if (in_map(xx,yy)) { if (dt.map[xx][yy].type==PERVIOUS) shft=0; if (dt.map[xx][yy].type==STONE) shft=INF; if (dt.map[xx][yy].type==BRICK) shft=2; if (dt.map[xx][yy].type==BREAKBRICK) shft=1; if ((get_hurt[xx][yy]<dt.tank[dt.map[now.row][now.col].whoIsHere].life)||(shft==1)||(shft==2)||((stop[tankID]>=3)&&(source_more(tankID))) ) if ( (t=dis(xx,yy,dt.source[min_sc].row,dt.source[min_sc].col))+shft<min_dd) { min_dd=t+shft; min_ord=i; min_shft=shft; } } } else for(i