这两天一直在搞这个AI,提供的样例更本不是我的风格啊,看不懂更不会改。。。
所以我自己写了一个AI的平台,现在在不断的修改AI的策略,smart样例还是很容易过的,让line的行走速度变慢一点到每回合15一下就可以了。这里大概写一下自己写了这么久,看了这么多别人的比赛的想法。
首先进攻分两种,一种是集群的进攻,一种是离散的进攻。集群进攻容易被拦截,但是攻击力充足(ps:规则允许多个水滴在同一个地方),离散进攻(如smart的两边)则攻击力相对较弱,但是不容易被拦截。line的进攻属于集群性进攻,有一些逗比的AI非常有效就是将中路一分为二从稍微靠上一点和稍微靠下一点走,然后就赢了。。。。防守一般是集群防守,因为张开的话火力不足而且比较慢。对付smart那种可以,但是对付line就挂了。。集群防守一般集中于大脑周围,但是也会有漏洞(水滴太少),所以应该加一个流动的机制,一旦有脑内未被打的敌方水滴,就过去打一下。这个写着有点麻烦。。。然后离散进攻的时候可以选择走没有人打得到的地方,然后就非常的慢,还要在优化一下。。。感觉以后要写得更高级恐怕KD树是不得不写了。。。
说一下我的AI平台,node代表水滴,水滴的命令有许多种,不详细介绍(看注释),大体流程是,读入-->下命令-->执行。有点像三国志9的模式。。。所有存活水滴用两个链表来存,代码如下(SymenAIalpha2)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 #include <ctime> 7 #include <cmath> 8 using namespace std; 9 10 struct position 11 { 12 int x; 13 int y; 14 15 position(int a=0,int b=0) 16 { 17 x=a;y=b; 18 } 19 20 bool outofrange() 21 { 22 return (x>10000)||(x<=0)||y>10000||y<=0; 23 } 24 }; 25 26 struct node 27 { 28 int number; 29 int level; 30 position pos; 31 position Gototar;//集合地 32 int tarnum;//攻击目标,-1,向Gototar移动,自由攻击 33 int blood; 34 35 int followNum;//和几号计划一样,虚拟计划,不是实体。0 == 没有计划 36 37 bool alive; 38 int movetype; 39 node* next; 40 node* last; 41 42 node(int a=0,position tar=position(9000,5000),int bl=20) 43 { 44 movetype=1; 45 alive=true; 46 number=a; 47 level=0; 48 Gototar=tar; 49 blood=bl; 50 tarnum=-1; 51 next=last=NULL; 52 followNum=0; 53 } 54 }; 55 56 node plan[1000]; 57 int plancnt=1; 58 node blue[325000]; 59 node red[325000]; 60 int nextred[325000]; 61 int nextblue[325000]; 62 int cntred=-1; 63 int cntblue=-1; 64 int BBB=5000; 65 int RBB=5000; 66 double getdis(node a,node b) {return sqrt((a.pos.x-b.pos.x)*(a.pos.x-b.pos.x)+(a.pos.y-b.pos.y)*(a.pos.y-b.pos.y));} 67 double getdis(node a,position b) {return sqrt((a.pos.x-b.x)*(a.pos.x-b.x)+(a.pos.y-b.y)*(a.pos.y-b.y));} 68 double getdis(position a,position b) {return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));} 69 70 bool inrand(node a,node b,int dis=30) 71 { 72 int far=dis+a.level*3; 73 double ds=getdis(a,b); 74 if (ds<=far) 75 return true; 76 return false; 77 } 78 bool inrand(node a,position b,int dis=30) 79 { 80 int far=dis+a.level*3; 81 double ds=getdis(a,b); 82 if (ds<=far) 83 return true; 84 return false; 85 } 86 87 int defcnt=0; 88 89 node* redl; 90 node* bluel; 91 92 node* Add(node* a,node* root) 93 { 94 if (!a->next) 95 { 96 a->next=root; 97 if (a->next) 98 a->next->last=a; 99 return a; 100 } 101 return NULL; 102 } 103 104 bool Dlt(node* now) 105 { 106 if (now->next) 107 { 108 if (now->last) 109 { 110 now->last->next=now->next; 111 now->next->last=now->last; 112 } 113 else 114 { 115 now->next->last=now->last; 116 } 117 return true; 118 } 119 else 120 { 121 if (now->last) 122 { 123 now->last->next=NULL; 124 return true; 125 } 126 else 127 { 128 return false; 129 } 130 } 131 } 132 133 node* Clean(node* root) 134 { 135 for (node* now=root;now;now=now->next) 136 { 137 if (!now->alive) 138 { 139 if (now==root) 140 root=now->next; 141 Dlt(now); 142 } 143 } 144 return root; 145 } 146 147 position GetNextStep(node a,node b,int dis=30) 148 { 149 double ds=getdis(a,b); 150 if (ds<=dis) return b.pos; 151 int dx=b.pos.x-a.pos.x; 152 int dy=b.pos.y-a.pos.y; 153 return position(a.pos.x+dx*(dis/ds),a.pos.y+dy*(dis/ds)); 154 } 155 int biao1[4]={-1,-1,1,1}; 156 int biao2[4]={-1,1,-1,1}; 157 int AvoidEps=400; 158 position GetNextStep2(node a,int b,int dis=30) 159 { 160 int type=plan[b].movetype; 161 if (type==1) 162 { 163 double ds=getdis(a,plan[b].Gototar); 164 if (ds<=dis) return plan[b].Gototar; 165 int dx=plan[b].Gototar.x-a.pos.x; 166 int dy=plan[b].Gototar.y-a.pos.y; 167 position ret=position(a.pos.x+dx*(dis/ds),a.pos.y+dy*(dis/ds)); 168 if (getdis(a,ret)>dis) ret.x--; 169 return ret; 170 } 171 if (type==2) 172 { 173 double ds=getdis(a,plan[b].Gototar); 174 // if (ds<=dis) return plan[b].Gototar; 175 int dx=plan[b].Gototar.x-a.pos.x; 176 int dy=plan[b].Gototar.y-a.pos.y; 177 int maxd=0x3f3f3f3f; 178 double minds=10101010101010.0; 179 position ret(0,0); 180 for (int i=-dis;i<=dis;++i) 181 { 182 for (int j=-dis;j<=dis;++j) 183 { 184 if (i*i+j*j>dis*dis) continue; 185 if (position(a.pos.x+i,a.pos.y+j).outofrange()) continue; 186 int sum=0; 187 for (node* now=bluel;now;now=now->next) 188 { 189 if (inrand(*now,position(a.pos.x+i,a.pos.y+j),AvoidEps)) sum++; 190 } 191 if (sum==maxd) 192 { 193 double ds2=getdis(plan[b].Gototar,position(a.pos.x+i,a.pos.y+j)); 194 if (ds2<minds) 195 { 196 minds=ds2; 197 ret=position(a.pos.x+i,a.pos.y+j); 198 } 199 } 200 if (sum<maxd) 201 { 202 maxd=sum; 203 ret=position(a.pos.x+i,a.pos.y+j); 204 } 205 } 206 } 207 return ret; 208 } 209 } 210 211 //#define Debug 212 position GetNextStep(node a,int dis=30) 213 { 214 int type=a.movetype; 215 if (type==1) 216 { 217 double ds=getdis(a,a.Gototar); 218 if (ds<=dis) return a.Gototar; 219 int dx=a.Gototar.x-a.pos.x; 220 int dy=a.Gototar.y-a.pos.y; 221 position ret=position(a.pos.x+dx*(dis/ds),a.pos.y+dy*(dis/ds)); 222 if (getdis(a,ret)>dis) ret.x--; 223 if (getdis(a,ret)>dis) ret.y--; 224 return ret; 225 } 226 if (type==2) 227 { 228 double ds=getdis(a,a.Gototar); 229 if (ds<=dis) return a.Gototar; 230 int maxd=0x3f3f3f3f; 231 double minds=12356434543.45; 232 position ret(0,0); 233 for (int i=-dis;i<=dis;++i) 234 { 235 for (int j=-dis;j<=dis;++j) 236 { 237 if (i*i+j*j>dis*dis) continue; 238 if (position(a.pos.x+i,a.pos.y+j).outofrange()) continue; 239 int sum=0; 240 for (node* now=bluel;now;now=now->next) 241 { 242 if (inrand(*now,position(a.pos.x+i,a.pos.y+j),AvoidEps)) 243 sum++; 244 } 245 if (sum==maxd) 246 { 247 double ds2=getdis(a.Gototar,position(a.pos.x+i,a.pos.y+j)); 248 if (ds2<minds) 249 { 250 minds=ds2; 251 ret=position(a.pos.x+i,a.pos.y+j); 252 } 253 } 254 if (sum<maxd) 255 { 256 maxd=sum; 257 ret=position(a.pos.x+i,a.pos.y+j); 258 } 259 } 260 } 261 return ret; 262 } 263 } 264 265 int RandomShoot(node a,int k=1) 266 { 267 int ret=-1; 268 double mindis=12334444444.0; 269 for (node* now=bluel;now;now=now->next) 270 { 271 if (inrand(a,*now)&&now->alive) 272 { 273 if (k==0) 274 return now->number; 275 if (k==1) 276 { 277 double ds=getdis(a,*now); 278 if (ds<mindis) 279 { 280 mindis=ds; 281 ret=now->number; 282 } 283 } 284 if (k==2) 285 { 286 if (now->pos.x<mindis) 287 { 288 mindis=now->pos.x; 289 ret=now->number; 290 } 291 } 292 } 293 } 294 return ret; 295 } 296 297 int sho[360000]; 298 int ta[360000]; 299 int nowbunum=0; 300 void Doit() 301 { 302 int atnum=0,monum=0; 303 //Att Turn 304 for (node* now=redl;now;now=now->next) 305 { 306 if (now->followNum) 307 { 308 int k=now->followNum; 309 if (plan[k].tarnum!=-1) 310 { 311 int tarnum=plan[k].tarnum; 312 if (blue[tarnum].alive) 313 { 314 now->level++; 315 atnum++; 316 sho[atnum]=now->number; 317 ta[atnum]=tarnum; 318 blue[tarnum].blood--; 319 if (blue[tarnum].blood==0) 320 { 321 blue[tarnum].alive=false; 322 plan[k].tarnum=-1; 323 } 324 } 325 } 326 else 327 { 328 int t=RandomShoot(*now); 329 if (t!=-1) 330 { 331 now->level++; 332 atnum++; 333 sho[atnum]=now->number; 334 ta[atnum]=t; 335 blue[t].blood--; 336 if (blue[t].blood==0) blue[t].alive=false; 337 } 338 } 339 continue; 340 } 341 if (now->tarnum!=-1) 342 { 343 int tarnum=now->tarnum; 344 if (blue[tarnum].alive) 345 { 346 now->level++; 347 atnum++; 348 sho[atnum]=now->number; 349 ta[atnum]=tarnum; 350 blue[tarnum].blood--; 351 if (blue[tarnum].blood==0) blue[tarnum].alive=false; 352 } 353 else 354 { 355 int t=RandomShoot(*now); 356 if (t!=-1) 357 { 358 now->level++; 359 atnum++; 360 sho[atnum]=now->number; 361 ta[atnum]=t; 362 blue[t].blood--; 363 if (blue[t].blood==0) blue[t].alive=false; 364 } 365 } 366 } 367 else 368 { 369 int t=RandomShoot(*now); 370 if (t!=-1) 371 { 372 now->level++; 373 atnum++; 374 sho[atnum]=now->number; 375 ta[atnum]=t; 376 blue[t].blood--; 377 if (blue[t].blood==0) blue[t].alive=false; 378 } 379 } 380 //End Att Turn 381 } 382 //print 383 { 384 printf("%d\n",atnum); 385 for (int i=1;i<=atnum;++i) 386 { 387 printf("%d %d\n",sho[i],ta[i]); 388 } 389 } 390 //End print 391 //MoveTurn 392 for (node* now=redl;now;now=now->next) 393 { 394 if (!now->followNum) 395 { 396 if (now->pos.x==now->Gototar.x&&now->pos.y==now->Gototar.y) continue; 397 monum++; 398 } 399 else 400 { 401 monum++; 402 } 403 } 404 //End MoveTurn 405 //Print 406 printf("%d\n",monum); 407 for (node* now=redl;now;now=now->next) 408 { 409 if (!now->followNum) 410 { 411 if (now->pos.x==now->Gototar.x&&now->pos.y==now->Gototar.y) continue; 412 position p=GetNextStep(*now); 413 now->pos=p; 414 printf("%d %d %d\n",now->number,p.x,p.y); 415 } 416 else 417 { 418 position p=GetNextStep2(*now,now->followNum); 419 now->pos=p; 420 printf("%d %d %d\n",now->number,p.x,p.y); 421 } 422 } 423 //End Print 424 //build 425 printf("%d\n",nowbunum); 426 for (int i=1;i<=nowbunum;++i) 427 { 428 cntred++; 429 red[cntred].pos=position(0,red[cntred].Gototar.y); 430 redl=Add(&red[cntred],redl); 431 printf("%d\n",red[cntred].pos.y); 432 } 433 nowbunum=0; 434 //End build 435 } 436 437 438 void init() 439 { 440 int ns; 441 scanf("%d",&ns); 442 for (int i=1;i<=ns;++i) 443 { 444 int sho,tar; 445 scanf("%d%d",&sho,&tar); 446 blue[sho].level++; 447 red[tar].blood--; 448 if (red[tar].blood==0) 449 { 450 red[tar].alive=false; 451 } 452 } 453 int nm; 454 scanf("%d",&nm); 455 for (int i=1;i<=nm;++i) 456 { 457 int mover,xx,yy; 458 scanf("%d%d%d",&mover,&xx,&yy); 459 blue[mover].pos=position(xx,yy); 460 } 461 int nn; 462 scanf("%d",&nn); 463 for (int i=1;i<=nn;++i) 464 { 465 ++cntblue; 466 int y; 467 scanf("%d",&y); 468 blue[cntblue].pos=position(10000,y); 469 bluel=Add(&blue[cntblue],bluel); 470 } 471 scanf("%d%d%d%d",&ns,&ns,&ns,&ns); 472 } 473 474 int _round=-1; 475 476 void AI() 477 { 478 ++_round; 479 if (_round%5==0) nowbunum++; 480 if (red[0].alive&&red[0].pos.x==9000) 481 { 482 red[0].Gototar=position(9000,5500); 483 } 484 if (plan[1].Gototar.x<=9000) 485 plan[1].Gototar.x+=13; 486 } 487 488 void PreMeet() 489 { 490 for (int i=1;i<325000;++i) 491 { 492 red[i].Gototar=position(1750,5000); 493 red[i].followNum=1; 494 blue[i].number=red[i].number=i; 495 } 496 plan[1].Gototar=position(1750,5000); 497 red[0].Gototar=position(9000,7999); 498 red[0].movetype=2; 499 cerr<<"Init Successfully"<<endl; 500 } 501 502 int main() 503 { 504 #ifdef Debug 505 freopen("blue.in","r",stdin); 506 #endif 507 PreMeet(); 508 while(true) 509 { 510 init(); 511 Clean(redl); 512 Clean(bluel); 513 cerr<<"Read Successfully"<<endl; 514 AI(); 515 cerr<<"AI Successfully"<<endl; 516 Doit(); 517 Clean(redl); 518 Clean(bluel); 519 cerr<<"Do Successfully"<<endl; 520 } 521 return 0; 522 }