这两天一直在搞这个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 }
296297 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 }
“国家队爷”杯液体战争AI比赛!!__SymenYang,布布扣,bubuko.com