maj degats + calcul flamme/gazor
[multileek.git] / src / IA_Exemple__4393.lks
blobd85c083b9c6ab1391068c3a6093e37f7a535c4ac
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                 if(currentWeaponSelected_l !== null){
84                         setWeapon(currentWeaponSelected_l);
85                 }
87                 pushAll(ITEMS_ATTACK_AVAILABLE_G, getWeapons());
88                 for(var itemIt_l in getChips()){
89                         if(STUFFS_G[itemIt_l] !== null &&
90                         STUFFS_G[itemIt_l][STUFF_DAMAGE_G][STUFF_VALUE_AVERAGE_G] != 0){
91                                 push(ITEMS_ATTACK_AVAILABLE_G, itemIt_l);
92                         }
93                         if(STUFFS_G[itemIt_l] !== null &&
94                         STUFFS_G[itemIt_l][STUFF_ABSOLUTE_G] != 0){
95                                 push(ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_ABSOLUTE_G]]);
96                         }
97                         if(STUFFS_G[itemIt_l] !== null &&
98                         STUFFS_G[itemIt_l][STUFF_RELATIVE_G] != 0){
99                                 push(ITEMS_DEFENSE_RELATIVE_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_RELATIVE_G]]);
100                         }
101                         if(STUFFS_G[itemIt_l] !== null &&
102                         STUFFS_G[itemIt_l][STUFF_AGILITY_G] != 0){
103                                 push(ITEMS_AGILITY_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_AGILITY_G]]);
104                         }
105                         if(STUFFS_G[itemIt_l] !== null &&
106                         STUFFS_G[itemIt_l][STUFF_STRENGTH_G] != 0){
107                                 push(ITEMS_STRENGTH_AVAILABLE_G, [itemIt_l, STUFFS_G[itemIt_l][STUFF_STRENGTH_G]]);
108                         }
109                         if(STUFFS_G[itemIt_l] !== null &&
110                         itemScoreTP(itemIt_l) != 0){
111                                 push(ITEMS_TP_AVAILABLE_G, [itemIt_l, itemScoreTP(itemIt_l)]);
112                         }
113                         if(STUFFS_G[itemIt_l] !== null &&
114                         itemScoreMP(itemIt_l) != 0){
115                                 push(ITEMS_MP_AVAILABLE_G, [itemIt_l, itemScoreMP(itemIt_l)]);
116                         }
117                 }
118                 assocSort(ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G, SORT_DESC);
119                 assocSort(ITEMS_DEFENSE_RELATIVE_AVAILABLE_G, SORT_DESC);
120                 assocSort(ITEMS_AGILITY_AVAILABLE_G, SORT_DESC);
121                 assocSort(ITEMS_STRENGTH_AVAILABLE_G, SORT_DESC);
122                 assocSort(ITEMS_TP_AVAILABLE_G, SORT_DESC);
123                 assocSort(ITEMS_MP_AVAILABLE_G, SORT_DESC);
125                 for(var itEnemy_l in getAliveEnemiesRobust()){
126                         PREVIOUS_ABSOLUTE_SHIELD_G[itEnemy_l] = 0;
127                         PREVIOUS_RELATIVE_SHIELD_G[itEnemy_l] = 0;
129                         LAST_TURN_ENEMY_USED_DEFENSE_G[itEnemy_l] = [];
130                         for(var itemIt_l in ITEMS_DEFENSE_RELATIVE_AVAILABLE_G){
131                                 LAST_TURN_ENEMY_USED_DEFENSE_G[itEnemy_l][itemIt_l[0]] = -999;
132                         }
133                         for(var itemIt_l in ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G){
134                                 LAST_TURN_ENEMY_USED_DEFENSE_G[itEnemy_l][itemIt_l[0]] = -999;
135                         }
136                 }
138                 IS_INITED_G = true;
139         }
141         /*var attacks_l = getItemCellScores();
142         debug("attacks_l=" + attacks_l);
143         var highScore_l = 0;
144         for(var score_l : var cellsItems_l in attacks_l){
145                 if(score_l > highScore_l){
146                         highScore_l = score_l;
147                 }
148         }
149         for(var score_l : var cellsItems_l in attacks_l){
150                 var color_l = getColor((255/(highScore_l + 1)) * (highScore_l + 1 - score_l), 0, 0);
151                 for(var cellItem_l in cellsItems_l){
152                         if(cellItem_l[0] == CHIP_SPARK){
153                                 mark([cellItem_l[1]], color_l);
154                         }
155                 }
156         }*/
157 debug("<<< init()");
162 function end(){
163 debug(">>> end()");
165         WEAKEST_ENEMY_G = getWeakestAliveEnemy();
166         if(LEVEL_G >= 5){
167                 PREVIOUS_POS_ENEMY_G = getCell(WEAKEST_ENEMY_G);
168         }
169 debug("<<< end()");
174 function fire(item_p, leek_p){
175 debug(">>> fire(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
177         var cellLeek_l = -1;
178         if(LEVEL_G >= 5) {
179                 cellLeek_l = getCell(leek_p);
180         }
181         if(isWeapon(item_p)){
182                 if(getWeapon() !== item_p){
183                         setWeapon(item_p);
184                 }
185                 useWeapon(leek_p);
186         }else if(isChip(item_p)){
187                 if(useChip(item_p, leek_p) == USE_SUCCESS){
188                         LAST_TURN_USED_CHIP_G[item_p] = TURN_G;
189                 }
190         }
191         if(isDead(leek_p)){
192                 WEAKEST_ENEMY_G = getWeakestAliveEnemy();
193                 removeKey(NON_EMPTY_CELLS_G, cellLeek_l);
194                 updateReachableCells();
195         }
196 debug("<<< fire(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
201 //si assez proche pour s'avancer et tirer sur leek_p : return 1
202 //si impossible : return 0
203 //si on ne sait pas : return -1
204 function closeEnoughToShoot(item_p, leek_p){
205 debug(">>> closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
207         var shootCell_l;
208         if(isWeapon(item_p)){
209                 shootCell_l = getCellToUseWeapon(item_p, leek_p);
210         }else if(isChip(item_p)){
211                 shootCell_l = getCellToUseChip(item_p, leek_p);
212         }
213         if(shootCell_l === null || shootCell_l == -1){
214 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
215                 return 0;
216         }
217         var currentCell_l = getCell();
218         if(currentCell_l === shootCell_l){
219 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 1");
220                 return 1;
221         }
222         var distToShootCell_l;
223         if(LEVEL_G < 5){
224                 if(getMP() === 0){
225 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
226                         return 0;
227                 }
228 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = -1");
229                 return -1;
230         }else{
231                 distToShootCell_l = getCellDistance(shootCell_l, currentCell_l);
232                 if(distToShootCell_l > getMP()){
233 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
234                         return 0;
235                 }
236                 if(LEVEL_G >= 37 && CORES_G >= 2){
237                         var pathLenght_l = getPathLength(shootCell_l, currentCell_l);
238                         if(pathLenght_l === null || pathLenght_l == -1){
239 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
240                                 return 0;
241                         }
242                         distToShootCell_l = pathLenght_l + 1;
243                         if(shootCell_l != currentCell_l && distToShootCell_l <= 0){
244 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
245                                 return 0;
246                         }
247                         if(distToShootCell_l > getMP()){
248 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
249                                 return 0;
250                         }else{
251 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 1");
252                                 return 1;
253                         }
254                 }
255         }
256 debug("<<< closeEnoughToShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = -1");
257         return -1;
262 //si possible de s'avancer et tirer sur leek_p : return 1
263 //si impossible : return 0
264 //si on ne sait pas : return -1
265 function canShoot(item_p, leek_p){
266 debug(">>> canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ")");
268         if(item_p === null || item_p == -1 ||
269                 leek_p === null || leek_p == -1){
270 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
271                 return 0;
272         }
273         //si pas assez de TP,
274         //impossible
275         if(getTP() < getStuffCostComplete(item_p)){
276 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
277                 return 0;
278         }
279         if(isChip(item_p)){
280                 //si le cooldown d'item_p est KO,
281                 //impossible
282                 if(LAST_TURN_USED_CHIP_G[item_p] != null &&
283                         getChipCooldown(item_p) > TURN_G - LAST_TURN_USED_CHIP_G[item_p]){
284 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = 0");
285                         return 0;
286                 }
287         }
288         //si pas assez proche,
289         //impossible
290 debug("<<< canShoot(" + getItemName(item_p) + ", " + getName(leek_p) + ") = <<<");
291         return closeEnoughToShoot(item_p, leek_p);
296 function isSafeToMoveToward(){
297 debug(">>> isSafeToMoveToward()");
299         var shootWeaponCell_l = getCellToUseWeapon(getNearestEnemy());
300         if(shootWeaponCell_l == -1 || LEVEL_G < 5){
301 debug("<<< isSafeToMoveToward() = true");
302                 return true;
303         }
304         var distToShootWeaponCell_l = getCellDistance(shootWeaponCell_l, getCell());
305 debug("<<< isSafeToMoveToward() = " + (distToShootWeaponCell_l > (MP_INIT_G + 1)));
306         return (distToShootWeaponCell_l > (MP_INIT_G + 1));
311 function isDraw(){
312 debug(">>> isDraw()");
314         if(LEVEL_G < 5){
315 debug("<<< isDraw() = true");
316                 return true;
317         }
318 debug("<<< isDraw() = " + (PREVIOUS_POS_ENEMY_G === getCell(WEAKEST_ENEMY_G)));
319         return (PREVIOUS_POS_ENEMY_G === getCell(WEAKEST_ENEMY_G));
324 function shoot(leek_p){
325 debug(">>> shoot(" + getName(leek_p) + ")");
326         if(getName(leek_p) === null){
327                 return;
328         }
330         var nbItemsAttack_l = count(ITEMS_ATTACK_AVAILABLE_G);
331         var itemIsTried_l = [];
332         var nbItemsTried_l = 0;
334         //tant qu'on a pas essaye de tout tirer
335         while(nbItemsTried_l < nbItemsAttack_l){
336                 //on selectionne l'item le plus interessant pas encore essaye
337                 var currentItemScore_l = -1;
338                 var currentItemSelected_l;
339                 for(var itemIt_l in ITEMS_ATTACK_AVAILABLE_G){
340                         if(itemIsTried_l[itemIt_l] == null &&
341                                 currentItemScore_l < itemScoreComplete(itemIt_l, 0, leek_p, true)){
342                                 currentItemSelected_l = itemIt_l;
343                                 currentItemScore_l = itemScoreComplete(itemIt_l, 0, leek_p, true);
344                         }
345                 }
346                 itemIsTried_l[currentItemSelected_l] = true;
347                 nbItemsTried_l++;
348                 debug("itemIsTried_l " + itemIsTried_l);
349                 debug("nbItemsTried_l " + nbItemsTried_l);
351                 if(currentItemScore_l > 0){
352                         //on va essayer de l'utiliser
353                         var shootCell_l;
354                         if(isChip(currentItemSelected_l)){
355                                 shootCell_l = getCellToUseChip(currentItemSelected_l, leek_p);
356                         }else{
357                                 shootCell_l = getCellToUseWeapon(currentItemSelected_l, leek_p);
358                         }
359                         //tant qu'on peut aller tirer
360                         while(canShoot(currentItemSelected_l, leek_p) != 0){
361                                 //si on est pas en position,
362                                 //on avance
363                                 if(shootCell_l != getCell()){
364                                         debug("avance currentItemSelected_l:" + currentItemSelected_l + " leek_p:" + leek_p);
365                                         if(LEVEL_G < 5){
366                                                 moveToward(leek_p, 1);
367                                                 if(isChip(currentItemSelected_l)){
368                                                         shootCell_l = getCellToUseChip(currentItemSelected_l, leek_p);
369                                                 }else{
370                                                         shootCell_l = getCellToUseWeapon(currentItemSelected_l, leek_p);
371                                                 }
372                                         }else{
373                                                 moveTowardCell(shootCell_l, 1);
374                                         }
375                                 }
376                                 debug("getCell()=" + getCell() + " shootCell_l=" + shootCell_l);
377                                 //si on est en position,
378                                 //on tire
379                                 if(shootCell_l === getCell()){
380                                         debug("tire currentItemSelected_l:" + currentItemSelected_l + " leek_p:" + leek_p);
381                                         var enemyBefore_l = leek_p;
382                                         fire(currentItemSelected_l, leek_p);
383                                         if(isDead(enemyBefore_l)){
384                                                 if(isChip(currentItemSelected_l)){
385                                                         shootCell_l = getCellToUseChip(currentItemSelected_l, leek_p);
386                                                 }else{
387                                                         shootCell_l = getCellToUseWeapon(currentItemSelected_l, leek_p);
388                                                 }
389                                         }
390                                 }
391                         }
392                 }
393         }
394 debug("<<< shoot(" + getName(leek_p) + ")");
399 function moveBefore(){
400 debug(">>> moveBefore()");
402         //si l'ennemi ne bouge pas ou qu'on peut avancer sans risque,
403         //on avance
404         if(isDraw() || isSafeToMoveToward()){
405                 moveToward(WEAKEST_ENEMY_G);
406         }
407 debug("<<< moveBefore()");
412 function moveAfter(){
413 debug(">>> moveAfter()");
415         if(LEVEL_G < 5){
416 debug("<<< moveAfter()");
417                 return;
418         }
419         var myCell_l = getCell();
420         var xMe_l = getCellX(myCell_l);
421         var yMe_l = getCellY(myCell_l);
422         debug("me = [" + xMe_l + "; " + yMe_l + "]");
423         var targetRetreat_l;
424         var cellEnemy_l = getCell(getNearestEnemy());
425         if(cellEnemy_l !== null && cellEnemy_l != -1){
426                 debug("enemy = [" + getCellX(cellEnemy_l) + "; " + getCellY(cellEnemy_l) + "]");
427                 var xDirectionEnemy_l = getCellX(cellEnemy_l) - xMe_l;
428                 var yDirectionEnemy_l = getCellY(cellEnemy_l) - yMe_l;
429                 if(abs(xDirectionEnemy_l) + abs(yDirectionEnemy_l) == 0)
430                 {
431                         moveAwayFrom(getNearestEnemy());
432                         debug("enemy same place?!");
433 debug("<<< moveAfter()");
434                         return;
435                 }
436                 if(getMP() == 0)
437                 {
438                         debug("no more MP");
439 debug("<<< moveAfter()");
440                         return;
441                 }
443                 if(abs(xDirectionEnemy_l) > abs(yDirectionEnemy_l)){
444                         if(yDirectionEnemy_l == 0)
445                         {
446                                 targetRetreat_l = getCellFromXY(xMe_l, yMe_l + getMP());
447                                 if(targetRetreat_l === null || targetRetreat_l == -1){
448                                         targetRetreat_l = getCellFromXY(xMe_l, yMe_l - getMP());
449                                 }
450                         }else{
451                                 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - signum(yDirectionEnemy_l)*getMP());
452                         }
453                 }else{
454                         if(xDirectionEnemy_l == 0)
455                         {
456                                 targetRetreat_l = getCellFromXY(xMe_l + getMP(), yMe_l);
457                                 if(targetRetreat_l === null || targetRetreat_l == -1){
458                                         targetRetreat_l = getCellFromXY(xMe_l - getMP(), yMe_l);
459                                 }
460                         }else{
461                                 targetRetreat_l = getCellFromXY(xMe_l - signum(yDirectionEnemy_l)*getMP(), yMe_l);
462                         }
463                 }
464         }
466         if(targetRetreat_l === null || targetRetreat_l == -1){
467                 debug("retraite nulle");
468                 //on vise le centre d'un cote du terrain le plus proche
469                 var possibleRetreats_l = [26, 298, 314, 598];
470                 var retreatDistance_l = 9999;
471                 for(var retreatIt_l in possibleRetreats_l){
472                         if(getCellDistance(myCell_l, retreatIt_l) < retreatDistance_l){
473                                 retreatDistance_l = getCellDistance(myCell_l, retreatIt_l);
474                                 targetRetreat_l = retreatIt_l;
475                         }
476                 }
477         }
478         moveTowardCell(targetRetreat_l);
479 debug("<<< moveAfter()");
484 global COEF_ESTIMATD_COMPLEXITY_G = 8;
485 global MIN_SECURITY_INSTRUCTION_G = 25000;
486 function retreat(){
487         //choper les couples item,enemy les plus dangereux
488         var itemEnemyDangerIt_l = 0;
489         var scoreTable_l = [];
490         var itemEnemyDistanceDanger_l = [];
491         for(var enemy_l in ENEMIES_G){
492                 if(isAlive(enemy_l)){
493                         for(var item_l : var average_l in getItemsAttack(enemy_l)){
494                                 if(canShootBasic(enemy_l, item_l)){
495                                         var probaCooldownOK_l = 1;
496                                         if(LEVEL_G >= 36){
497                                                 if(isChip(item_l) && getCooldown(item_l, enemy_l) > 1){
498                                                         probaCooldownOK_l = 0;
499                                                 }
500                                         }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
501                                                         && STUFFS_G[item_l][STUFF_COOLDOWN_G] > 1){
502                                                 probaCooldownOK_l = 1/STUFFS_G[item_l][STUFF_COOLDOWN_G];
503                                         }
504                                         for(var distance_l = 0; distance_l <= STUFFS_G[item_l][STUFF_RADIUS_G]; distance_l++){
505                                                 push(itemEnemyDistanceDanger_l, [item_l, enemy_l, distance_l]);
506                                                 scoreTable_l[itemEnemyDangerIt_l] = getNbAttackComplete(enemy_l, item_l) * probaCooldownOK_l * expectedDamage(enemy_l, item_l, ME_G, distance_l);
507                                                 itemEnemyDangerIt_l++;
508                                         }
509                                 }
510                         }
511                 }
512         }
513         assocSort(scoreTable_l, SORT_DESC);
514         updateReachableCells();
515         var retreatCells_l = [];
516         for(var cellIt_l : var pathIt_l in REACHABLE_CELLS_G){
517                 retreatCells_l[cellIt_l] = 1;
518         }
519         var previousEnemy_l = -1;
520         var mapItemMapEnemyNoHiding_l = [];
521         for(itemEnemyDangerIt_l : var score_l in scoreTable_l) {
522                 var nbInstructionBeginItemScore_l = getInstructionsCount();
523                 var enemy_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][1];
524                 var cellsReachablebleEnemy_l = getReachableCellCloseToMe(LEEK_MOVEMENTS_G[enemy_l][TURN_G], LEEKS_VARIABLE_CARAC_G[enemy_l][TURN_G][CARAC_MP]);
525                 var estimatedComplexity_l = count(cellsReachablebleEnemy_l) * count(retreatCells_l) * COEF_ESTIMATD_COMPLEXITY_G;
526                 var securityInstructions_l = MIN_SECURITY_INSTRUCTION_G;
527                 if(estimatedComplexity_l > securityInstructions_l){
528                         securityInstructions_l = estimatedComplexity_l;
529                 }
530                 if(INSTRUCTIONS_LIMIT - getInstructionsCount() < securityInstructions_l){
531                         break;
532                 }
534                 var item_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][0];
535                 if(mapItemMapEnemyNoHiding_l[item_l] !== null
536                                 && mapItemMapEnemyNoHiding_l[item_l][enemy_l] !== null){
537                         continue;
538                 }
539                 var distance_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][2];
540                 var currentRetreatCells = retreatCells_l;
541                 //on elimine les cellules dangereuses
542                 if(distance_l > 0) {
543                         var outEdge_l = getDistantBorder(retreatCells_l, distance_l);
544                         for(var hurtableCellMe_l : var cellsProducingIt_l in outEdge_l[distance_l - 1]){
545                                 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
546                                         if(mightShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, hurtableCellMe_l, ME_G)){
547                                                 var cellsToRemove_l = [];
548                                                 push(cellsToRemove_l, hurtableCellMe_l);
549                                                 for(var itDist_l = 0; itDist_l < distance_l; itDist_l++){
550                                                         var newCellsToRemove_l = [];
551                                                         for(var itCellCurrentBorder in cellsToRemove_l){
552                                                                 pushAll(newCellsToRemove_l, outEdge_l[distance_l - 1 - itDist_l][itCellCurrentBorder]);
553                                                         }
554                                                         cellsToRemove_l = newCellsToRemove_l;
555                                                 }
556                                                 for(var cellIt_l in cellsToRemove_l){
557                                                         removeKey(currentRetreatCells, cellIt_l);
558                                                 }
559                                                 break;
560                                         }
561                                         if(count(currentRetreatCells) == 0){
562                                                 break;
563                                         }
564                                 }
565                                 if(count(currentRetreatCells) == 0){
566                                         break;
567                                 }
568                         }
569                 }else{
570                         for(var reachableCellMe_l : var pathMe_l in retreatCells_l){
571                                 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
572                                         if(mightShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, reachableCellMe_l, ME_G)){
573                                                 removeKey(currentRetreatCells, reachableCellMe_l);
574                                                 break;
575                                         }
576                                 }
577                         }
578                 }
579                 if(count(currentRetreatCells) > 0){
580                         retreatCells_l = currentRetreatCells;
581                 }else{
582                         if(mapItemMapEnemyNoHiding_l[item_l] === null){
583                                 mapItemMapEnemyNoHiding_l[item_l] = [];
584                         }
585                         mapItemMapEnemyNoHiding_l[item_l][enemy_l] = 1;
586                 }
588                 var nbInstructions_l = getInstructionsCount() - nbInstructionBeginItemScore_l;
589                 var estimationQuality_l = nbInstructions_l / estimatedComplexity_l;
590                 if(nbInstructions_l > MIN_SECURITY_INSTRUCTION_G && estimationQuality_l > 1){
591                         COEF_ESTIMATD_COMPLEXITY_G *= estimationQuality_l;
592                         debugE("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". New COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
593                 }else if(nbInstructions_l > 0.5 * MIN_SECURITY_INSTRUCTION_G && estimationQuality_l < 0.7){
594                         debugW("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
595                 }else{
596                         debug("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
597                 }
598         }
600         var distanceWeakest_l = 10000;
601         var distanceCenter_l = 10000;
602         var targetCell_l = 306;
603         var weakestCell_l = LEEK_MOVEMENTS_G[WEAKEST_ENEMY_G][TURN_G];
604         for(var cellIt_l : var distanceEnemyIt_l in retreatCells_l){
605                 var distanceEnemy_l = 0;
606                 if(weakestCell_l !== null){
607                         distanceEnemy_l = getPathLength(cellIt_l, weakestCell_l);
608                 }
609                 if(LEVEL_G > 5
610                                 && ((distanceEnemy_l < distanceWeakest_l)
611                                         ||(distanceEnemy_l == distanceWeakest_l && getCellDistance(cellIt_l, 306) < distanceCenter_l))){
612                         distanceWeakest_l = distanceEnemy_l;
613                         distanceCenter_l = getCellDistance(cellIt_l, 306);
614                         targetCell_l = cellIt_l;
615                 }
616         }
617         for(var pathCell_l in REACHABLE_CELLS_G[targetCell_l][0]){
618                 moveToCell(pathCell_l, 1);
619         }
620         if(targetCell_l !== getCell()){
621                 moveToCell(targetCell_l, 1);
622         }
627 function defendIfHasDefended(leek_p, item_p){
628 debug(">>> defendIfHasDefended(" + getName(leek_p) + ", " + getItemName(item_p) + ")");
630         var cost_l = STUFFS_G[item_p][STUFF_COST_G];
631         var mustDefend_l = false;
632         if(LEVEL_G >= 38){
633                 if(STUFFS_G[item_p][STUFF_RELATIVE_G] > 0){
634                         if(getRelativeShield(leek_p) - PREVIOUS_RELATIVE_SHIELD_G[leek_p] >= STUFFS_G[item_p][STUFF_RELATIVE_G]// + getAgility(leek_p) / 50
635                         ){
636                                 mustDefend_l = true;
637                         }
638                 }
639                 if(STUFFS_G[item_p][STUFF_ABSOLUTE_G] > 0){
640                         if(getAbsoluteShield(leek_p) - PREVIOUS_ABSOLUTE_SHIELD_G[leek_p] >= STUFFS_G[item_p][STUFF_ABSOLUTE_G]// * (1 + getAgility(leek_p) / 100)
641                         ){
642                                 mustDefend_l = true;
643                                 if(getTP() >= cost_l + STUFFS_G[CHIP_STRETCHING][STUFF_COST_G]){
644                                         useChip(CHIP_STRETCHING, ME_G);
645                                 }
646                         }
647                 }
648         }
649         if(mustDefend_l == true || LEVEL_G < 38){
650                 LAST_TURN_ENEMY_USED_DEFENSE_G[leek_p][item_p] = TURN_G;
651                 if(getTP() >= cost_l){
652                         useChip(item_p, ME_G);
653                 }
654         }
655 debug("<<< defendIfHasDefended(" + getName(leek_p) + ", " + getItemName(item_p) + ")");
660 function defense(enemy_p){
661 debug(">>> defense(" + getName(enemy_p) + ")");
663         for(var itemDefRel_l in ITEMS_DEFENSE_RELATIVE_AVAILABLE_G){
664                 defendIfHasDefended(enemy_p, itemDefRel_l[0]);
665         }
666         for(var itemDefAbs_l in ITEMS_DEFENSE_ABSOLUTE_AVAILABLE_G){
667                 defendIfHasDefended(enemy_p, itemDefAbs_l[0]);
668         }
670         if(LEVEL_G >= 38){
671                 for(var itEnemy_l in getAliveEnemiesRobust()){
672                         PREVIOUS_ABSOLUTE_SHIELD_G[itEnemy_l] = getAbsoluteShield(itEnemy_l);
673                         PREVIOUS_RELATIVE_SHIELD_G[itEnemy_l] = getRelativeShield(itEnemy_l);
674                 }
675         }
676 debug("<<< defense(" + getName(enemy_p) + ")");
681 function renforce(enemy_p){
682 debug(">>> renforce(" + getName(enemy_p) + ")");
684         debug(LAST_TURN_ENEMY_USED_DEFENSE_G);
685         for(var itemDefIt_l : var defTurnIt_l in LAST_TURN_ENEMY_USED_DEFENSE_G[enemy_p]){
686                 if(defTurnIt_l + STUFFS_G[itemDefIt_l][STUFF_DURATION_G] -1 == TURN_G){
687                         for(var itemForceIt_l in ITEMS_STRENGTH_AVAILABLE_G){
688                                 if(getTP() >= STUFFS_G[itemForceIt_l[0]][STUFF_COST_G]){
689                                         useChip(itemForceIt_l[0], ME_G);
690                                 }
691                         }
692                 }
693         }
694 debug("<<< renforce(" + getName(enemy_p) + ")");
699 function boostTPAfter(){
700 debug(">>> boostTPAfter()");
702         for(var itemTPIt_l in ITEMS_TP_AVAILABLE_G){
703                 if(getTP() >= STUFFS_G[itemTPIt_l[0]][STUFF_COST_G]){
704                         useChip(itemTPIt_l[0], ME_G);
705                 }
706         }
707 debug("<<< boostTPAfter()");
712 function boostMPAfter(){
713 debug(">>> boostMPAfter()");
715         for(var itemMPIt_l in ITEMS_MP_AVAILABLE_G){
716                 if(getTP() >= STUFFS_G[itemMPIt_l[0]][STUFF_COST_G]){
717                         useChip(itemMPIt_l[0], ME_G);
718                 }
719         }
720 debug("<<< boostMPAfter()");
725 function renforceAfter(enemy_p){
726 debug(">>> renforceAfter(" + getName(enemy_p) + ")");
728         var canRenforce = true;
729         var turnMinCanRenforce = MAX_TURNS;
730         for(var itemDefIt_l : var defTurnIt_l in LAST_TURN_ENEMY_USED_DEFENSE_G[enemy_p]){
731                 if(!(defTurnIt_l + STUFFS_G[itemDefIt_l][STUFF_DURATION_G] < TURN_G
732                                 && (defTurnIt_l > 0 || STUFFS_G[itemDefIt_l][STUFF_DURATION_G] < TURN_G))){
733                         canRenforce = false;
734                 }
735         }
736         if(canRenforce){
737                 for(var itemForceIt_l in ITEMS_STRENGTH_AVAILABLE_G){
738                         if(getTP() >= STUFFS_G[itemForceIt_l[0]][STUFF_COST_G]){
739                                 useChip(itemForceIt_l[0], ME_G);
740                         }
741                 }
742         }
743 debug("<<< renforceAfter(" + getName(enemy_p) + ")");
748 function canKill(enemy_p){
749 debug(">>> canKill(" + getName(enemy_p) + ")");
751         var currentItemScore_l = -1;
752         var currentItemSelected_l;
753         for(var itemIt_l in ITEMS_ATTACK_AVAILABLE_G){
754                 if(currentItemScore_l < itemScoreComplete(itemIt_l, 0, enemy_p, false)){
755                         currentItemSelected_l = itemIt_l;
756                         currentItemScore_l = itemScoreComplete(itemIt_l, 0, enemy_p, false);
757                 }
758         }
760         if(currentItemScore_l >= getLife(enemy_p)){
761 debug("<<< canKill(" + getName(enemy_p) + ") = true");
762                 return true;
763         }
764 debug("<<< canKill(" + getName(enemy_p) + ") = false");
765         return false;
770 function killIfPossible(){
771 debug(">>> killIfPossible()");
773         for(var itEnemy_l in getAliveEnemiesRobust()){
774                 if(canKill(itEnemy_l)){
775                         shoot(itEnemy_l);
776                 }
777         }
778 debug("<<< killIfPossible()");
783 //----- main -----
785 //si defi lance par ennemi,
786 //actions de base
787 init();
788 debug("[count] init:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
789 var nameNearest_l = getName(getNearestEnemy());
790 if(LEVEL_G >= 14 && getFightContext() === FIGHT_CONTEXT_CHALLENGE
791                 && isEnemy(0)
792                 && !(nameNearest_l === "LeekSkinteur"
793                         || nameNearest_l === "LeekHeFacteur"
794                         || nameNearest_l === "LessCrabouilleur"
795                         || nameNearest_l === "pibourrin"
796                         || nameNearest_l === "poirTouz"
797                         || nameNearest_l === "poirTage"
798                         || nameNearest_l === "Marie75"
799                         || nameNearest_l === "Marie75001")){
800         var enemy = getNearestEnemy();
801         if(LEVEL_G >= 5){
802                 moveTowardCell(getCellToUseWeapon(enemy));
803         }else{
804                 moveToward(enemy);
805         }
806         useWeapon(enemy);
807 }else{
808         killIfPossible();
809         renforce(WEAKEST_ENEMY_G);
810         defense(WEAKEST_ENEMY_G);
811         shoot(getNearestEnemy());
812         shoot(WEAKEST_ENEMY_G);
813         //moveBefore();
814         debug("[count] shoot:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
816         boostTPAfter();
817         boostMPAfter();
818         renforceAfter(WEAKEST_ENEMY_G);
819         retreat();
820         //moveAfter();
821         debug("[count] moveAfter:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
823         end();
824         debug("[count] end:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);