首页 > 代码库 > “国家队爷”杯液体战争AI比赛!!__SymenYang

“国家队爷”杯液体战争AI比赛!!__SymenYang

原帖

  这两天一直在搞这个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 }
View Code