differenciation entre usage retreat et attack (ignore leeks ou pas)
[multileek.git] / src / IA_Exemple__4393.lks
blob2fccaf8c69596b71aa99da9fa1a413f80065cf78
1 // NAME : IA_Exemple
2 // DEFINITION : main
3 //
4 // TODEBUG : pourquoi doping pas utilise?
5 // TODO : favoriser le coup qui renforce le plus le rapport viePibou/vieEnemy
6 // TODO : utiliser liberation apres lui (si besoin), et amender "renforcer" selon
7 // TODO : comprendre http://leekwars.com/fight/4772483 et http://leekwars.com/report/4774414
8 // TODO : utiliser casque bas niveau
9 // TODO : reperer quand alternance casque/forteresse (pas 40 de diff)
10 // TODO : tirer a cote (armes avec zone)
11 // TODO : ameliorer isSafeToMoveToward (tirer en premier)
12 // TODO : utiliser fonction de tri pour shoot
13 // TODO : refactor, utiliser cell to shoot plutot que leek si possible
14 // TODO : guerison le tour d'apres si boost agilite
15 // TODO : pas trop pres quand item affecte une zone (decaler tir ou decaler leek)
16 // TODO : shouldAttack & enemyVulnerable?
17 // TODO : soin que quand utile (niveau 21)
18 // TODO : choix de l'arme utilisee meilleur (partir du ratio gain/cout avec le itemScore a une arme, puis essayer de permuter avec seulement les armes qui ont un ratio de base superieur)
19 // TODO : http://leekwars.com/fight/7696767 a eviter
21 // TOWATCH : surveiller la fonction weakest qui fluctue avec la force (la faire une fois pour toute au début?)
22 // TOWATCH : surveiller http://leekwars.com/forum/category-7/topic-763
24 // TOTEST : http://leekwars.com/farmer/13071
26 include("include_basic_global_variables");
27 include("include_STUFFS_G");
28 include("include_getWeakestAliveEnemy");
29 include("include_ground");
30 include("include_leeks");
31 include("include_shoot");
33 global IS_INITED_G = false;
35 global WEAKEST_ENEMY_G = null;
36 global PREVIOUS_POS_ENEMY_G = null;
37 global MP_INIT_G = getMP();
38 global TP_INIT_G = getTP();
39 global LAST_TURN_USED_CHIP_G = [];
40 global ITEMS_ATTACK_AVAILABLE_G = [];
41 global ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G = [];
42 global ITEMS_DEFENSE_RELATIVE_AVAILABLE_G = [];
43 global ITEMS_AGILITY_AVAILABLE_G = [];
44 global ITEMS_STRENGTH_AVAILABLE_G = [];
45 global ITEMS_TP_AVAILABLE_G = [];
46 global ITEMS_MP_AVAILABLE_G = [];
48 global PREVIOUS_ABSOLUTE_SHIELD_G = [];
49 global PREVIOUS_RELATIVE_SHIELD_G = [];
50 global LAST_TURN_ENEMY_USED_DEFENSE_G = [];
54 function init(){
55 debug(">>> init()");
57         TURN_G++;
58         if(!IS_INITED_G) {
59                 initObstaclesEnemiesAlliesPositions();
60                 initLeeksCarac();
61                 debug("LEEKS_CONSTANT_CARAC_G = " + LEEKS_CONSTANT_CARAC_G);
62         }
63         initLeeksCaracTurn();
64         debug("LEEKS_VARIABLE_CARAC_G = " + LEEKS_VARIABLE_CARAC_G);
65         initLeeksPositionTurn();
66         debug("LEEK_MOVEMENTS_G = " + LEEK_MOVEMENTS_G);
67         updateReachableCells();
69         WEAKEST_ENEMY_G = getWeakestAliveEnemy();
70         if(LEVEL_G >= 5){
71                 PREVIOUS_POS_ENEMY_G = getCell(WEAKEST_ENEMY_G);
72         }
73         if(!IS_INITED_G){
74                 var currentWeaponScore_l = 0;
75                 var currentWeaponSelected_l;
76                 for(var weaponIt_l in getWeapons()){
77                         if(STUFFS_G[weaponIt_l] !== null &&
78                         currentWeaponScore_l < itemScoreRatioBasic(weaponIt_l, WEAKEST_ENEMY_G)){
79                                 currentWeaponSelected_l = weaponIt_l;
80                                 currentWeaponScore_l = itemScoreRatioBasic(weaponIt_l, WEAKEST_ENEMY_G);
81                         }
82                 }
83                 setWeapon(currentWeaponSelected_l);
85                 pushAll(ITEMS_ATTACK_AVAILABLE_G, getWeapons());
86                 for(var itemIt_l in getChips()){
87                         if(STUFFS_G[itemIt_l] !== null &&
88                         STUFFS_G[itemIt_l][STUFF_DAMAGE_G][STUFF_VALUE_AVERAGE_G] != 0){
89                                 push(ITEMS_ATTACK_AVAILABLE_G, itemIt_l);
90                         }
91                         if(STUFFS_G[itemIt_l] !== null &&
92                         STUFFS_G[itemIt_l][STUFF_ABSOLUTE_G] != 0){
93                                 push(ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_ABSOLUTE_G]]);
94                         }
95                         if(STUFFS_G[itemIt_l] !== null &&
96                         STUFFS_G[itemIt_l][STUFF_RELATIVE_G] != 0){
97                                 push(ITEMS_DEFENSE_RELATIVE_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_RELATIVE_G]]);
98                         }
99                         if(STUFFS_G[itemIt_l] !== null &&
100                         STUFFS_G[itemIt_l][STUFF_AGILITY_G] != 0){
101                                 push(ITEMS_AGILITY_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_AGILITY_G]]);
102                         }
103                         if(STUFFS_G[itemIt_l] !== null &&
104                         STUFFS_G[itemIt_l][STUFF_STRENGTH_G] != 0){
105                                 push(ITEMS_STRENGTH_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_STRENGTH_G]]);
106                         }
107                         if(STUFFS_G[itemIt_l] !== null &&
108                         itemScoreTP(itemIt_l) != 0){
109                                 push(ITEMS_TP_AVAILABLE_G, [itemIt_l, itemScoreTP(itemIt_l)]);
110                         }
111                         if(STUFFS_G[itemIt_l] !== null &&
112                         itemScoreMP(itemIt_l) != 0){
113                                 push(ITEMS_MP_AVAILABLE_G, [itemIt_l, itemScoreMP(itemIt_l)]);
114                         }
115                 }
116                 assocSort(ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G, SORT_DESC);
117                 assocSort(ITEMS_DEFENSE_RELATIVE_AVAILABLE_G, SORT_DESC);
118                 assocSort(ITEMS_AGILITY_AVAILABLE_G, SORT_DESC);
119                 assocSort(ITEMS_STRENGTH_AVAILABLE_G, SORT_DESC);
120                 assocSort(ITEMS_TP_AVAILABLE_G, SORT_DESC);
121                 assocSort(ITEMS_MP_AVAILABLE_G, SORT_DESC);
123                 for(var itEnemy_l in getAliveEnemiesRobust()){
124                         PREVIOUS_ABSOLUTE_SHIELD_G[itEnemy_l] = 0;
125                         PREVIOUS_RELATIVE_SHIELD_G[itEnemy_l] = 0;
127                         LAST_TURN_ENEMY_USED_DEFENSE_G[itEnemy_l] = [];
128                         for(var itemIt_l in ITEMS_DEFENSE_RELATIVE_AVAILABLE_G){
129                                 LAST_TURN_ENEMY_USED_DEFENSE_G[itEnemy_l][itemIt_l[0]] = -999;
130                         }
131                         for(var itemIt_l in ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G){
132                                 LAST_TURN_ENEMY_USED_DEFENSE_G[itEnemy_l][itemIt_l[0]] = -999;
133                         }
134                 }
136                 IS_INITED_G = true;
137         }
139         /*var attacks_l = getItemCellScores();
140         debug("attacks_l=" + attacks_l);
141         var highScore_l = 0;
142         for(var score_l : var cellsItems_l in attacks_l){
143                 if(score_l > highScore_l){
144                         highScore_l = score_l;
145                 }
146         }
147         for(var score_l : var cellsItems_l in attacks_l){
148                 var color_l = getColor((255/(highScore_l + 1)) * (highScore_l + 1 - score_l), 0, 0);
149                 for(var cellItem_l in cellsItems_l){
150                         if(cellItem_l[0] == CHIP_SPARK){
151                                 mark([cellItem_l[1]], color_l);
152                         }
153                 }
154         }*/
155 debug("<<< init()");
160 function end(){
161 debug(">>> end()");
163         WEAKEST_ENEMY_G = getWeakestAliveEnemy();
164         if(LEVEL_G >= 5){
165                 PREVIOUS_POS_ENEMY_G = getCell(WEAKEST_ENEMY_G);
166         }
167 debug("<<< end()");
172 function fire(item_p, leek_p){
173 debug(">>> fire(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
175         var cellLeek_l = -1;
176         if(LEVEL_G >= 5) {
177                 cellLeek_l = getCell(leek_p);
178         }
179         if(isWeapon(item_p)){
180                 if(getWeapon() !== item_p){
181                         setWeapon(item_p);
182                 }
183                 useWeapon(leek_p);
184         }else if(isChip(item_p)){
185                 if(useChip(item_p, leek_p) == USE_SUCCESS){
186                         LAST_TURN_USED_CHIP_G[item_p] = TURN_G;
187                 }
188         }
189         if(isDead(leek_p)){
190                 WEAKEST_ENEMY_G = getWeakestAliveEnemy();
191                 removeKey(NON_EMPTY_CELLS_G, cellLeek_l);
192                 updateReachableCells();
193         }
194 debug("<<< fire(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
199 //si assez proche pour s'avancer et tirer sur leek_p : return 1
200 //si impossible : return 0
201 //si on ne sait pas : return -1
202 function closeEnoughToShoot(item_p, leek_p){
203 debug(">>> closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
205         var shootCell_l;
206         if(isWeapon(item_p)){
207                 shootCell_l = getCellToUseWeapon(item_p, leek_p);
208         }else if(isChip(item_p)){
209                 shootCell_l = getCellToUseChip(item_p, leek_p);
210         }
211         if(shootCell_l === null || shootCell_l == -1){
212 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
213                 return 0;
214         }
215         var currentCell_l = getCell();
216         if(currentCell_l === shootCell_l){
217 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 1");
218                 return 1;
219         }
220         var distToShootCell_l;
221         if(LEVEL_G < 5){
222                 if(getMP() === 0){
223 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
224                         return 0;
225                 }
226 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = -1");
227                 return -1;
228         }else{
229                 distToShootCell_l = getCellDistance(shootCell_l, currentCell_l);
230                 if(distToShootCell_l > getMP()){
231 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
232                         return 0;
233                 }
234                 if(LEVEL_G >= 37 && CORES_G >= 2){
235                         var pathLenght_l = getPathLength(shootCell_l, currentCell_l);
236                         if(pathLenght_l === null || pathLenght_l == -1){
237 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
238                                 return 0;
239                         }
240                         distToShootCell_l = pathLenght_l + 1;
241                         if(shootCell_l != currentCell_l && distToShootCell_l <= 0){
242 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
243                                 return 0;
244                         }
245                         if(distToShootCell_l > getMP()){
246 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
247                                 return 0;
248                         }else{
249 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 1");
250                                 return 1;
251                         }
252                 }
253         }
254 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = -1");
255         return -1;
260 //si possible de s'avancer et tirer sur leek_p : return 1
261 //si impossible : return 0
262 //si on ne sait pas : return -1
263 function canShoot(item_p, leek_p){
264 debug(">>> canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
266         if(item_p === null || item_p == -1 ||
267                 leek_p === null || leek_p == -1){
268 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
269                 return 0;
270         }
271         //si pas assez de TP,
272         //impossible
273         if(getTP() < getStuffCostComplete(item_p)){
274 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
275                 return 0;
276         }
277         if(isChip(item_p)){
278                 //si le cooldown d'item_p est KO,
279                 //impossible
280                 if(LAST_TURN_USED_CHIP_G[item_p] != null &&
281                         getChipCooldown(item_p) > TURN_G - LAST_TURN_USED_CHIP_G[item_p]){
282 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
283                         return 0;
284                 }
285         }
286         //si pas assez proche,
287         //impossible
288 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = <<<");
289         return closeEnoughToShoot(item_p, leek_p);
294 function isSafeToMoveToward(){
295 debug(">>> isSafeToMoveToward()");
297         var shootWeaponCell_l = getCellToUseWeapon(getNearestEnemy());
298         if(shootWeaponCell_l == -1 || LEVEL_G < 5){
299 debug("<<< isSafeToMoveToward() = true");
300                 return true;
301         }
302         var distToShootWeaponCell_l = getCellDistance(shootWeaponCell_l, getCell());
303 debug("<<< isSafeToMoveToward() = " + (distToShootWeaponCell_l > (MP_INIT_G + 1)));
304         return (distToShootWeaponCell_l > (MP_INIT_G + 1));
309 function isDraw(){
310 debug(">>> isDraw()");
312         if(LEVEL_G < 5){
313 debug("<<< isDraw() = true");
314                 return true;
315         }
316 debug("<<< isDraw() = " + (PREVIOUS_POS_ENEMY_G === getCell(WEAKEST_ENEMY_G)));
317         return (PREVIOUS_POS_ENEMY_G === getCell(WEAKEST_ENEMY_G));
322 function shoot(leek_p){
323 debug(">>> shoot(" + getName(leek_p) + ")");
324         if(getName(leek_p) === null){
325                 return;
326         }
328         var nbItemsAttack_l = count(ITEMS_ATTACK_AVAILABLE_G);
329         var itemIsTried_l = [];
330         var nbItemsTried_l = 0;
332         //tant qu'on a pas essaye de tout tirer
333         while(nbItemsTried_l < nbItemsAttack_l){
334                 //on selectionne l'item le plus interessant pas encore essaye
335                 var currentItemScore_l = -1;
336                 var currentItemSelected_l;
337                 for(var itemIt_l in ITEMS_ATTACK_AVAILABLE_G){
338                         if(itemIsTried_l[itemIt_l] == null &&
339                                 currentItemScore_l < itemScoreComplete(itemIt_l, 0, leek_p, true)){
340                                 currentItemSelected_l = itemIt_l;
341                                 currentItemScore_l = itemScoreComplete(itemIt_l, 0, leek_p, true);
342                         }
343                 }
344                 itemIsTried_l[currentItemSelected_l] = true;
345                 nbItemsTried_l++;
346                 debug("itemIsTried_l " + itemIsTried_l);
347                 debug("nbItemsTried_l " + nbItemsTried_l);
349                 if(currentItemScore_l > 0){
350                         //on va essayer de l'utiliser
351                         var shootCell_l;
352                         if(isChip(currentItemSelected_l)){
353                                 shootCell_l = getCellToUseChip(currentItemSelected_l, leek_p);
354                         }else{
355                                 shootCell_l = getCellToUseWeapon(currentItemSelected_l, leek_p);
356                         }
357                         //tant qu'on peut aller tirer
358                         while(canShoot(currentItemSelected_l, leek_p) != 0){
359                                 //si on est pas en position,
360                                 //on avance
361                                 if(shootCell_l != getCell()){
362                                         debug("avance currentItemSelected_l:" + currentItemSelected_l + " leek_p:" + leek_p);
363                                         if(LEVEL_G < 5){
364                                                 moveToward(leek_p, 1);
365                                                 if(isChip(currentItemSelected_l)){
366                                                         shootCell_l = getCellToUseChip(currentItemSelected_l, leek_p);
367                                                 }else{
368                                                         shootCell_l = getCellToUseWeapon(currentItemSelected_l, leek_p);
369                                                 }
370                                         }else{
371                                                 moveTowardCell(shootCell_l, 1);
372                                         }
373                                 }
374                                 debug("getCell()=" + getCell() + " shootCell_l=" + shootCell_l);
375                                 //si on est en position,
376                                 //on tire
377                                 if(shootCell_l === getCell()){
378                                         debug("tire currentItemSelected_l:" + currentItemSelected_l + " leek_p:" + leek_p);
379                                         var enemyBefore_l = leek_p;
380                                         fire(currentItemSelected_l, leek_p);
381                                         if(isDead(enemyBefore_l)){
382                                                 if(isChip(currentItemSelected_l)){
383                                                         shootCell_l = getCellToUseChip(currentItemSelected_l, leek_p);
384                                                 }else{
385                                                         shootCell_l = getCellToUseWeapon(currentItemSelected_l, leek_p);
386                                                 }
387                                         }
388                                 }
389                         }
390                 }
391         }
392 debug("<<< shoot(" + getName(leek_p) + ")");
397 function moveBefore(){
398 debug(">>> moveBefore()");
400         //si l'ennemi ne bouge pas ou qu'on peut avancer sans risque,
401         //on avance
402         if(isDraw() || isSafeToMoveToward()){
403                 moveToward(WEAKEST_ENEMY_G);
404         }
405 debug("<<< moveBefore()");
410 function moveAfter(){
411 debug(">>> moveAfter()");
413         if(LEVEL_G < 5){
414 debug("<<< moveAfter()");
415                 return;
416         }
417         var myCell_l = getCell();
418         var xMe_l = getCellX(myCell_l);
419         var yMe_l = getCellY(myCell_l);
420         debug("me = [" + xMe_l + "; " + yMe_l + "]");
421         var targetRetreat_l;
422         var cellEnemy_l = getCell(getNearestEnemy());
423         if(cellEnemy_l !== null && cellEnemy_l != -1){
424                 debug("enemy = [" + getCellX(cellEnemy_l) + "; " + getCellY(cellEnemy_l) + "]");
425                 var xDirectionEnemy_l = getCellX(cellEnemy_l) - xMe_l;
426                 var yDirectionEnemy_l = getCellY(cellEnemy_l) - yMe_l;
427                 if(abs(xDirectionEnemy_l) + abs(yDirectionEnemy_l) == 0)
428                 {
429                         moveAwayFrom(getNearestEnemy());
430                         debug("enemy same place?!");
431 debug("<<< moveAfter()");
432                         return;
433                 }
434                 if(getMP() == 0)
435                 {
436                         debug("no more MP");
437 debug("<<< moveAfter()");
438                         return;
439                 }
441                 if(abs(xDirectionEnemy_l) > abs(yDirectionEnemy_l)){
442                         if(yDirectionEnemy_l == 0)
443                         {
444                                 targetRetreat_l = getCellFromXY(xMe_l, yMe_l + getMP());
445                                 if(targetRetreat_l === null || targetRetreat_l == -1){
446                                         targetRetreat_l = getCellFromXY(xMe_l, yMe_l - getMP());
447                                 }
448                         }else{
449                                 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - signum(yDirectionEnemy_l)*getMP());
450                         }
451                 }else{
452                         if(xDirectionEnemy_l == 0)
453                         {
454                                 targetRetreat_l = getCellFromXY(xMe_l + getMP(), yMe_l);
455                                 if(targetRetreat_l === null || targetRetreat_l == -1){
456                                         targetRetreat_l = getCellFromXY(xMe_l - getMP(), yMe_l);
457                                 }
458                         }else{
459                                 targetRetreat_l = getCellFromXY(xMe_l - signum(yDirectionEnemy_l)*getMP(), yMe_l);
460                         }
461                 }
462         }
464         if(targetRetreat_l === null || targetRetreat_l == -1){
465                 debug("retraite nulle");
466                 //on vise le centre d'un cote du terrain le plus proche
467                 var possibleRetreats_l = [26, 298, 314, 598];
468                 var retreatDistance_l = 9999;
469                 for(var retreatIt_l in possibleRetreats_l){
470                         if(getCellDistance(myCell_l, retreatIt_l) < retreatDistance_l){
471                                 retreatDistance_l = getCellDistance(myCell_l, retreatIt_l);
472                                 targetRetreat_l = retreatIt_l;
473                         }
474                 }
475         }
476         moveTowardCell(targetRetreat_l);
477 debug("<<< moveAfter()");
482 global COEF_ESTIMATD_COMPLEXITY_G = 8;
483 global MIN_SECURITY_INSTRUCTION_G = 25000;
484 function retreat(){
485         //choper les couples item,enemy les plus dangereux
486         var itemEnemyDangerIt_l = 0;
487         var scoreTable_l = [];
488         var itemEnemyDistanceDanger_l = [];
489         for(var enemy_l in ENEMIES_G){
490                 if(isAlive(enemy_l)){
491                         for(var item_l : var average_l in getItemsAttack(enemy_l)){
492                                 if(canShootBasic(enemy_l, item_l)){
493                                         var probaCooldownOK_l = 1;
494                                         if(LEVEL_G >= 36){
495                                                 if(isChip(item_l) && getCooldown(item_l, enemy_l) > 1){
496                                                         probaCooldownOK_l = 0;
497                                                 }
498                                         }else if(LEEKS_VARIABLE_CARAC_G[ME_G][0][CARAC_LIFE] - LEEKS_VARIABLE_CARAC_G[ME_G][TURN_G][CARAC_LIFE] > LEEKS_VARIABLE_CARAC_G[ME_G][0][CARAC_LIFE] * 0.2
499                                                         && STUFFS_G[item_l][STUFF_COOLDOWN_G] > 1){
500                                                 probaCooldownOK_l = 1/STUFFS_G[item_l][STUFF_COOLDOWN_G];
501                                         }
502                                         for(var distance_l = 0; distance_l <= STUFFS_G[item_l][STUFF_RADIUS_G]; distance_l++){
503                                                 push(itemEnemyDistanceDanger_l, [item_l, enemy_l, distance_l]);
504                                                 scoreTable_l[itemEnemyDangerIt_l] = getNbAttackComplete(enemy_l, item_l) * probaCooldownOK_l * expectedDamage(enemy_l, item_l, ME_G, distance_l);
505                                                 itemEnemyDangerIt_l++;
506                                         }
507                                 }
508                         }
509                 }
510         }
511         assocSort(scoreTable_l, SORT_DESC);
512         updateReachableCells();
513         var retreatCells_l = [];
514         for(var cellIt_l : var pathIt_l in REACHABLE_CELLS_G){
515                 retreatCells_l[cellIt_l] = 1;
516         }
517         var previousEnemy_l = -1;
518         var mapItemMapEnemyNoHiding_l = [];
519         for(itemEnemyDangerIt_l : var score_l in scoreTable_l) {
520                 var nbInstructionBeginItemScore_l = getInstructionsCount();
521                 var enemy_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][1];
522                 var cellsReachablebleEnemy_l = getReachableCellCloseToMe(LEEK_MOVEMENTS_G[enemy_l][TURN_G], LEEKS_VARIABLE_CARAC_G[enemy_l][TURN_G][CARAC_MP]);
523                 var estimatedComplexity_l = count(cellsReachablebleEnemy_l) * count(retreatCells_l) * COEF_ESTIMATD_COMPLEXITY_G;
524                 var securityInstructions_l = MIN_SECURITY_INSTRUCTION_G;
525                 if(estimatedComplexity_l > securityInstructions_l){
526                         securityInstructions_l = estimatedComplexity_l;
527                 }
528                 if(INSTRUCTIONS_LIMIT - getInstructionsCount() < securityInstructions_l){
529                         break;
530                 }
532                 var item_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][0];
533                 if(mapItemMapEnemyNoHiding_l[item_l] !== null
534                                 && mapItemMapEnemyNoHiding_l[item_l][enemy_l] !== null){
535                         continue;
536                 }
537                 var distance_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][2];
538                 var currentRetreatCells = retreatCells_l;
539                 //on elimine les cellules dangereuses
540                 if(distance_l > 0) {
541                         var outEdge_l = getDistantBorder(retreatCells_l, distance_l);
542                         for(var hurtableCellMe_l : var cellsProducingIt_l in outEdge_l[distance_l - 1]){
543                                 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
544                                         if(mightShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, hurtableCellMe_l, ME_G)){
545                                                 var cellsToRemove_l = [];
546                                                 push(cellsToRemove_l, hurtableCellMe_l);
547                                                 for(var itDist_l = 0; itDist_l < distance_l; itDist_l++){
548                                                         var newCellsToRemove_l = [];
549                                                         for(var itCellCurrentBorder in cellsToRemove_l){
550                                                                 pushAll(newCellsToRemove_l, outEdge_l[distance_l - 1 - itDist_l][itCellCurrentBorder]);
551                                                         }
552                                                         cellsToRemove_l = newCellsToRemove_l;
553                                                 }
554                                                 for(var cellIt_l in cellsToRemove_l){
555                                                         removeKey(currentRetreatCells, cellIt_l);
556                                                 }
557                                                 break;
558                                         }
559                                         if(count(currentRetreatCells) == 0){
560                                                 break;
561                                         }
562                                 }
563                                 if(count(currentRetreatCells) == 0){
564                                         break;
565                                 }
566                         }
567                 }else{
568                         for(var reachableCellMe_l : var pathMe_l in retreatCells_l){
569                                 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
570                                         if(mightShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, reachableCellMe_l, ME_G)){
571                                                 removeKey(currentRetreatCells, reachableCellMe_l);
572                                                 break;
573                                         }
574                                 }
575                         }
576                 }
577                 if(count(currentRetreatCells) > 0){
578                         retreatCells_l = currentRetreatCells;
579                 }else{
580                         if(mapItemMapEnemyNoHiding_l[item_l] === null){
581                                 mapItemMapEnemyNoHiding_l[item_l] = [];
582                         }
583                         mapItemMapEnemyNoHiding_l[item_l][enemy_l] = 1;
584                 }
586                 var nbInstructions_l = getInstructionsCount() - nbInstructionBeginItemScore_l;
587                 var estimationQuality_l = nbInstructions_l / estimatedComplexity_l;
588                 if(nbInstructions_l > MIN_SECURITY_INSTRUCTION_G && estimationQuality_l > 1){
589                         COEF_ESTIMATD_COMPLEXITY_G *= estimationQuality_l;
590                         debugE("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". New COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
591                 }else if(nbInstructions_l > 0.5 * MIN_SECURITY_INSTRUCTION_G && estimationQuality_l < 0.7){
592                         debugW("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
593                 }else{
594                         debug("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
595                 }
596         }
598         var distanceWeakest_l = 10000;
599         var distanceCenter_l = 10000;
600         var targetCell_l = 306;
601         var weakestCell_l = LEEK_MOVEMENTS_G[WEAKEST_ENEMY_G][TURN_G];
602         for(var cellIt_l : var distanceEnemyIt_l in retreatCells_l){
603                 var distanceEnemy_l = 0;
604                 if(weakestCell_l !== null){
605                         distanceEnemy_l = getCellDistance(cellIt_l, weakestCell_l);
606                 }
607                 if(LEVEL_G > 5
608                                 && ((distanceEnemy_l < distanceWeakest_l)
609                                         ||(distanceEnemy_l == distanceWeakest_l && getCellDistance(cellIt_l, 306) < distanceCenter_l))){
610                         distanceWeakest_l = distanceEnemy_l;
611                         distanceCenter_l = getCellDistance(cellIt_l, 306);
612                         targetCell_l = cellIt_l;
613                 }
614         }
615         for(var pathCell_l in REACHABLE_CELLS_G[targetCell_l][0]){
616                 moveToCell(pathCell_l, 1);
617         }
618         if(targetCell_l !== getCell()){
619                 moveToCell(targetCell_l, 1);
620         }
625 function defendIfHasDefended(leek_p, item_p){
626 debug(">>> defendIfHasDefended(" + getName(leek_p) + ", " + getItemName(item_p) + ")");
628         var cost_l = STUFFS_G[item_p][STUFF_COST_G];
629         var mustDefend_l = false;
630         if(LEVEL_G >= 38){
631                 if(STUFFS_G[item_p][STUFF_RELATIVE_G] > 0){
632                         if(getRelativeShield(leek_p) - PREVIOUS_RELATIVE_SHIELD_G[leek_p] >= STUFFS_G[item_p][STUFF_RELATIVE_G]// + getAgility(leek_p) / 50
633                         ){
634                                 mustDefend_l = true;
635                         }
636                 }
637                 if(STUFFS_G[item_p][STUFF_ABSOLUTE_G] > 0){
638                         if(getAbsoluteShield(leek_p) - PREVIOUS_ABSOLUTE_SHIELD_G[leek_p] >= STUFFS_G[item_p][STUFF_ABSOLUTE_G]// * (1 + getAgility(leek_p) / 100)
639                         ){
640                                 mustDefend_l = true;
641                                 if(getTP() >= cost_l + STUFFS_G[CHIP_STRETCHING][STUFF_COST_G]){
642                                         useChip(CHIP_STRETCHING, ME_G);
643                                 }
644                         }
645                 }
646         }
647         if(mustDefend_l == true || LEVEL_G < 38){
648                 LAST_TURN_ENEMY_USED_DEFENSE_G[leek_p][item_p] = TURN_G;
649                 if(getTP() >= cost_l){
650                         useChip(item_p, ME_G);
651                 }
652         }
653 debug("<<< defendIfHasDefended(" + getName(leek_p) + ", " + getItemName(item_p) + ")");
658 function defense(enemy_p){
659 debug(">>> defense(" + getName(enemy_p) + ")");
661         for(var itemDefRel_l in ITEMS_DEFENSE_RELATIVE_AVAILABLE_G){
662                 defendIfHasDefended(enemy_p, itemDefRel_l[0]);
663         }
664         for(var itemDefAbs_l in ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G){
665                 defendIfHasDefended(enemy_p, itemDefAbs_l[0]);
666         }
668         if(LEVEL_G >= 38){
669                 for(var itEnemy_l in getAliveEnemiesRobust()){
670                         PREVIOUS_ABSOLUTE_SHIELD_G[itEnemy_l] = getAbsoluteShield(itEnemy_l);
671                         PREVIOUS_RELATIVE_SHIELD_G[itEnemy_l] = getRelativeShield(itEnemy_l);
672                 }
673         }
674 debug("<<< defense(" + getName(enemy_p) + ")");
679 function renforce(enemy_p){
680 debug(">>> renforce(" + getName(enemy_p) + ")");
682         debug(LAST_TURN_ENEMY_USED_DEFENSE_G);
683         for(var itemDefIt_l : var defTurnIt_l in LAST_TURN_ENEMY_USED_DEFENSE_G[enemy_p]){
684                 if(defTurnIt_l + STUFFS_G[itemDefIt_l][STUFF_DURATION_G] -1 == TURN_G){
685                         for(var itemForceIt_l in ITEMS_STRENGTH_AVAILABLE_G){
686                                 if(getTP() >= STUFFS_G[itemForceIt_l[0]][STUFF_COST_G]){
687                                         useChip(itemForceIt_l[0], ME_G);
688                                 }
689                         }
690                 }
691         }
692 debug("<<< renforce(" + getName(enemy_p) + ")");
697 function boostTPAfter(){
698 debug(">>> boostTPAfter()");
700         for(var itemTPIt_l in ITEMS_TP_AVAILABLE_G){
701                 if(getTP() >= STUFFS_G[itemTPIt_l[0]][STUFF_COST_G]){
702                         useChip(itemTPIt_l[0], ME_G);
703                 }
704         }
705 debug("<<< boostTPAfter()");
710 function boostMPAfter(){
711 debug(">>> boostMPAfter()");
713         for(var itemMPIt_l in ITEMS_MP_AVAILABLE_G){
714                 if(getTP() >= STUFFS_G[itemMPIt_l[0]][STUFF_COST_G]){
715                         useChip(itemMPIt_l[0], ME_G);
716                 }
717         }
718 debug("<<< boostMPAfter()");
723 function renforceAfter(enemy_p){
724 debug(">>> renforceAfter(" + getName(enemy_p) + ")");
726         var canRenforce = true;
727         var turnMinCanRenforce = MAX_TURNS;
728         for(var itemDefIt_l : var defTurnIt_l in LAST_TURN_ENEMY_USED_DEFENSE_G[enemy_p]){
729                 if(!(defTurnIt_l + STUFFS_G[itemDefIt_l][STUFF_DURATION_G] < TURN_G
730                                 && (defTurnIt_l > 0 || STUFFS_G[itemDefIt_l][STUFF_DURATION_G] < TURN_G))){
731                         canRenforce = false;
732                 }
733         }
734         if(canRenforce){
735                 for(var itemForceIt_l in ITEMS_STRENGTH_AVAILABLE_G){
736                         if(getTP() >= STUFFS_G[itemForceIt_l[0]][STUFF_COST_G]){
737                                 useChip(itemForceIt_l[0], ME_G);
738                         }
739                 }
740         }
741 debug("<<< renforceAfter(" + getName(enemy_p) + ")");
746 function canKill(enemy_p){
747 debug(">>> canKill(" + getName(enemy_p) + ")");
749         var currentItemScore_l = -1;
750         var currentItemSelected_l;
751         for(var itemIt_l in ITEMS_ATTACK_AVAILABLE_G){
752                 if(currentItemScore_l < itemScoreComplete(itemIt_l, 0, enemy_p, false)){
753                         currentItemSelected_l = itemIt_l;
754                         currentItemScore_l = itemScoreComplete(itemIt_l, 0, enemy_p, false);
755                 }
756         }
758         if(currentItemScore_l >= getLife(enemy_p)){
759 debug("<<< canKill(" + getName(enemy_p) + ") = true");
760                 return true;
761         }
762 debug("<<< canKill(" + getName(enemy_p) + ") = false");
763         return false;
768 function killIfPossible(){
769 debug(">>> killIfPossible()");
771         for(var itEnemy_l in getAliveEnemiesRobust()){
772                 if(canKill(itEnemy_l)){
773                         shoot(itEnemy_l);
774                 }
775         }
776 debug("<<< killIfPossible()");
781 //----- main -----
783 //si defi lance par ennemi,
784 //actions de base
785 init();
786 debug("[count] init:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
787 var nameNearest_l = getName(getNearestEnemy());
788 if(LEVEL_G >= 14 && getFightContext() === FIGHT_CONTEXT_CHALLENGE
789                 && isEnemy(0)
790                 && !(nameNearest_l === "LeekSkinteur"
791                         || nameNearest_l === "LeekHeFacteur"
792                         || nameNearest_l === "LessCrabouilleur"
793                         || nameNearest_l === "pibourrin"
794                         || nameNearest_l === "poirTouz"
795                         || nameNearest_l === "poirTage"
796                         || nameNearest_l === "Marie75"
797                         || nameNearest_l === "Marie75001")){
798         var enemy = getNearestEnemy();
799         if(LEVEL_G >= 5){
800                 moveTowardCell(getCellToUseWeapon(enemy));
801         }else{
802                 moveToward(enemy);
803         }
804         useWeapon(enemy);
805 }else{
806         killIfPossible();
807         renforce(WEAKEST_ENEMY_G);
808         defense(WEAKEST_ENEMY_G);
809         shoot(getNearestEnemy());
810         shoot(WEAKEST_ENEMY_G);
811         //moveBefore();
812         debug("[count] shoot:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
814         boostTPAfter();
815         boostMPAfter();
816         renforceAfter(WEAKEST_ENEMY_G);
817         retreat();
818         //moveAfter();
819         debug("[count] moveAfter:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
821         end();
822         debug("[count] end:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);