4 // TODEBUG : pourquoi doping pas utilise?
5 // TODO : shoot fonctionne pas pour plusieurs déplacements
6 // TODO : getAttackableCell peut gagner en complexité (aller droit dans 4 directions, puis à droite pr chaque avec décrément)
7 // TODO : favoriser le coup qui renforce le plus le rapport viePibou/vieEnemy
8 // TODO : utiliser liberation apres lui (si besoin), et amender "renforcer" selon
9 // TODO : comprendre http://leekwars.com/fight/4772483 et http://leekwars.com/report/4774414
10 // TODO : utiliser casque bas niveau
11 // TODO : reperer quand alternance casque/forteresse (pas 40 de diff)
12 // TODO : tirer a cote (armes avec zone)
13 // TODO : ameliorer isSafeToMoveToward (tirer en premier)
14 // TODO : utiliser fonction de tri pour shoot
15 // TODO : refactor, utiliser cell to shoot plutot que leek si possible
16 // TODO : guerison le tour d'apres si boost agilite
17 // TODO : pas trop pres quand item affecte une zone (decaler tir ou decaler leek)
18 // TODO : shouldAttack & enemyVulnerable?
19 // TODO : soin que quand utile (niveau 21)
20 // 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)
22 // TOWATCH : surveiller la fonction weakest qui fluctue avec la force (la faire une fois pour toute au début?)
23 // TOWATCH : surveiller http://leekwars.com/forum/category-7/topic-763
25 // TOTEST : http://leekwars.com/farmer/13071
27 include("include_basic_global_variables");
28 include("include_STUFFS_G");
29 include("include_getWeakestAliveEnemy");
30 include("include_ground");
31 include("include_leeks");
32 include("include_shoot");
34 global IS_INITED_G = false;
36 global WEAKEST_ENEMY_G = null;
38 global LAST_TURN_ENEMY_USED_DEFENSE_G = [];
47 initObstaclesEnemiesAlliesPositions();
49 debug("LEEKS_CONSTANT_CARAC_G = " + LEEKS_CONSTANT_CARAC_G);
52 debug("LEEKS_VARIABLE_CARAC_G = " + LEEKS_VARIABLE_CARAC_G);
53 initLeeksPositionTurn();
54 debug("LEEK_MOVEMENTS_G = " + LEEK_MOVEMENTS_G);
55 updateReachableCells();
57 WEAKEST_ENEMY_G = getWeakestAliveEnemy();
59 var currentWeaponScore_l = 0;
60 var currentWeaponSelected_l;
61 for(var weaponIt_l in getWeapons()){
62 if(STUFFS_G[weaponIt_l] !== null &&
63 currentWeaponScore_l < itemScoreRatioBasic(weaponIt_l, WEAKEST_ENEMY_G)){
64 currentWeaponSelected_l = weaponIt_l;
65 currentWeaponScore_l = itemScoreRatioBasic(weaponIt_l, WEAKEST_ENEMY_G);
68 setWeapon(currentWeaponSelected_l);
80 WEAKEST_ENEMY_G = getWeakestAliveEnemy();
86 function fire(item_p, cell_p, leek_p){
87 debug(">>> fire(" + getItemName(item_p) + ", " + cell_p + ", " + getName(leek_p) + ")");
91 cellLeek_l = getCell(leek_p);
94 if(getWeapon() !== item_p){
97 if(cell_p !== null && cell_p < 612 && cell_p >= 0){
98 useWeaponOnCell(cell_p);
102 }else if(isChip(item_p)){
103 if(useChip(item_p, leek_p) == USE_SUCCESS){
104 LEEKS_VARIABLE_CARAC_G[ME_G][0][CARAC_LAST_TURN_USED_CHIP][item_p] = TURN_G;
106 if(cell_p !== null && cell_p < 612 && cell_p >= 0){
107 if(useChipOnCell(item_p, cell_p) == USE_SUCCESS){
108 LEEKS_VARIABLE_CARAC_G[ME_G][0][CARAC_LAST_TURN_USED_CHIP][item_p] = TURN_G;
111 if(useChip(item_p, leek_p) == USE_SUCCESS){
112 LEEKS_VARIABLE_CARAC_G[ME_G][0][CARAC_LAST_TURN_USED_CHIP][item_p] = TURN_G;
116 var enemyWasKilled_l = false;
117 for(var leekIt_l in ENEMIES_G){
118 if(LEEKS_VARIABLE_CARAC_G[leekIt_l][TURN_G][CARAC_LIFE] !== 0
119 && isDead(leekIt_l)){
120 enemyWasKilled_l = true;
121 removeKey(NON_EMPTY_CELLS_G, cellLeek_l);
124 if(enemyWasKilled_l){
125 WEAKEST_ENEMY_G = getWeakestAliveEnemy();
126 updateReachableCells();
128 debug("<<< fire(" + getItemName(item_p) + ", " + cell_p + ", " + getName(leek_p) + ")");
133 debug(">>> shoot()");
135 var itemCellScores_l = getItemCellScores();
136 for(var index_l : var score_l in itemCellScores_l[1]){
137 debug("score_l = " + score_l + " itemCell_l = " + itemCellScores_l[0][index_l]);
139 var reachableTemp_l = [];
140 reachableTemp_l[getCell()] = [[], 0];
141 for(var reachableCell_l : var path_l in REACHABLE_CELLS_G){
142 reachableTemp_l[reachableCell_l] = path_l;
144 for(var reachableCell_l : var path_l in REACHABLE_CELLS_G){
145 var item_l = itemCellScores_l[0][index_l][0];
146 var targetCell_l = itemCellScores_l[0][index_l][1];
147 var damageME_l = itemScore(item_l, getCellDistance(reachableCell_l, targetCell_l), getNbAttackComplete(ME_G, item_l), ME_G, true);
148 if(item_l === CHIP_LIGHTNING){
151 if(canShootComplete(reachableCell_l, ME_G, item_l, targetCell_l, WEAKEST_ENEMY_G) == 1 && damageME_l <= 0){
152 for(var pathCell_l in path_l[0]){
153 moveToCell(pathCell_l, 1);
155 if(reachableCell_l !== getCell()){
156 moveToCell(reachableCell_l, 1);
157 updateReachableCells();
159 while(canShootBasic(ME_G, item_l)){
160 fire(item_l, targetCell_l, WEAKEST_ENEMY_G);
166 debug("<<< shoot()");
171 global COEF_ESTIMATD_COMPLEXITY_G = 8;
172 global MIN_SECURITY_INSTRUCTION_G = 25000;
174 //choper les couples item,enemy les plus dangereux
175 var itemEnemyDangerIt_l = 0;
176 var scoreTable_l = [];
177 var itemEnemyDanger_l = [];
178 for(var enemy_l in ENEMIES_G){
179 if(isAlive(enemy_l)){
180 for(var item_l : var average_l in getItemsAttack(enemy_l)){
181 if(canShootBasic(enemy_l, item_l)){
182 var probaCooldownOK_l = 1;
184 if(isChip(item_l) && getCooldown(item_l, enemy_l) > 1){
185 probaCooldownOK_l = 0;
187 }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
188 && STUFFS_G[item_l][STUFF_COOLDOWN_G] > 1){
189 probaCooldownOK_l = 1/STUFFS_G[item_l][STUFF_COOLDOWN_G];
191 push(itemEnemyDanger_l, [item_l, enemy_l]);
192 scoreTable_l[itemEnemyDangerIt_l] = getNbAttackComplete(enemy_l, item_l) * probaCooldownOK_l * expectedDamage(enemy_l, item_l, ME_G, 0);
193 itemEnemyDangerIt_l++;
198 assocSort(scoreTable_l, SORT_DESC);
199 updateReachableCells();
200 var retreatCells_l = [];
201 for(var cellIt_l : var pathIt_l in REACHABLE_CELLS_G){
202 retreatCells_l[cellIt_l] = 1;
204 var previousEnemy_l = -1;
205 for(itemEnemyDangerIt_l : var score_l in scoreTable_l) {
206 var nbInstructionBeginItemScore_l = getInstructionsCount();
207 var item_l = itemEnemyDanger_l[itemEnemyDangerIt_l][0];
208 var enemy_l = itemEnemyDanger_l[itemEnemyDangerIt_l][1];
209 var cellsReachablebleEnemy_l = getReachableCellCloseToMe(LEEK_MOVEMENTS_G[enemy_l][TURN_G], LEEKS_VARIABLE_CARAC_G[enemy_l][TURN_G][CARAC_MP]);
210 var estimatedComplexity_l = count(cellsReachablebleEnemy_l) * count(retreatCells_l) * COEF_ESTIMATD_COMPLEXITY_G;
211 var securityInstructions_l = MIN_SECURITY_INSTRUCTION_G;
212 if(estimatedComplexity_l > securityInstructions_l){
213 securityInstructions_l = estimatedComplexity_l;
215 if(INSTRUCTIONS_LIMIT - getInstructionsCount() < securityInstructions_l){
219 var currentRetreatCells = retreatCells_l;
220 //on elimine les cellules dangereuse
221 for(var reachableCellMe_l : var pathMe_l in retreatCells_l){
222 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
223 if(canShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, reachableCellMe_l, ME_G)){
224 removeKey(currentRetreatCells, reachableCellMe_l);
229 if(count(currentRetreatCells) > 0){
230 retreatCells_l = currentRetreatCells;
233 var nbInstructions_l = getInstructionsCount() - nbInstructionBeginItemScore_l;
234 var estimationQuality_l = nbInstructions_l / estimatedComplexity_l;
235 if(nbInstructions_l > MIN_SECURITY_INSTRUCTION_G && estimationQuality_l > 1){
236 COEF_ESTIMATD_COMPLEXITY_G *= estimationQuality_l;
237 debugE("nbInstructions_l = " + nbInstructions_l + " and estimationQuality_l = " + estimationQuality_l + ". New COEF_ESTIMATD_COMPLEXITY_G = " + COEF_ESTIMATD_COMPLEXITY_G);
238 }else if(nbInstructions_l > 0.5 * MIN_SECURITY_INSTRUCTION_G && estimationQuality_l < 0.7){
239 debugW("nbInstructions_l = " + nbInstructions_l + " and estimationQuality_l = " + estimationQuality_l + ". New COEF_ESTIMATD_COMPLEXITY_G = " + COEF_ESTIMATD_COMPLEXITY_G);
241 debug("nbInstructions_l = " + nbInstructions_l + " and estimationQuality_l = " + estimationQuality_l);
245 var distanceWeakest_l = 10000;
246 var distanceCenter_l = 10000;
247 var targetCell_l = 306;
248 var weakestCell_l = LEEK_MOVEMENTS_G[WEAKEST_ENEMY_G][TURN_G];
249 for(var cellIt_l : var distanceEnemyIt_l in retreatCells_l){
251 && ((getCellDistance(cellIt_l, weakestCell_l) < distanceWeakest_l)
252 ||(getCellDistance(cellIt_l, weakestCell_l) == distanceWeakest_l && getCellDistance(cellIt_l, 306) < distanceCenter_l))){
253 distanceWeakest_l = getCellDistance(cellIt_l, weakestCell_l);
254 distanceCenter_l = getCellDistance(cellIt_l, 306);
255 targetCell_l = cellIt_l;
258 for(var pathCell_l in REACHABLE_CELLS_G[targetCell_l][0]){
259 moveToCell(pathCell_l, 1);
261 if(targetCell_l !== getCell()){
262 moveToCell(targetCell_l, 1);
267 function moveAfter(){
268 debug(">>> moveAfter()");
271 debug("<<< moveAfter()");
274 var myCell_l = getCell();
275 var xMe_l = getCellX(myCell_l);
276 var yMe_l = getCellY(myCell_l);
277 debug("me = [" + xMe_l + "; " + yMe_l + "]");
279 var cellEnemy_l = getCell(getNearestEnemy());
280 if(cellEnemy_l !== null && cellEnemy_l != -1){
281 debug("enemy = [" + getCellX(cellEnemy_l) + "; " + getCellY(cellEnemy_l) + "]");
282 var xDirectionEnemy_l = getCellX(cellEnemy_l) - xMe_l;
283 var yDirectionEnemy_l = getCellY(cellEnemy_l) - yMe_l;
284 if(abs(xDirectionEnemy_l) + abs(yDirectionEnemy_l) == 0)
286 moveAwayFrom(getNearestEnemy());
287 debug("enemy same place?!");
288 debug("<<< moveAfter()");
294 debug("<<< moveAfter()");
298 if(abs(xDirectionEnemy_l) > abs(yDirectionEnemy_l)){
299 if(yDirectionEnemy_l == 0)
301 targetRetreat_l = getCellFromXY(xMe_l, yMe_l + getMP());
302 if(targetRetreat_l === null || targetRetreat_l == -1){
303 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - getMP());
306 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - signum(yDirectionEnemy_l)*getMP());
309 if(xDirectionEnemy_l == 0)
311 targetRetreat_l = getCellFromXY(xMe_l + getMP(), yMe_l);
312 if(targetRetreat_l === null || targetRetreat_l == -1){
313 targetRetreat_l = getCellFromXY(xMe_l - getMP(), yMe_l);
316 targetRetreat_l = getCellFromXY(xMe_l - signum(yDirectionEnemy_l)*getMP(), yMe_l);
321 if(targetRetreat_l === null || targetRetreat_l == -1){
322 debug("retraite nulle");
323 //on vise le centre d'un cote du terrain le plus proche
324 var possibleRetreats_l = [26, 298, 314, 598];
325 var retreatDistance_l = 9999;
326 for(var retreatIt_l in possibleRetreats_l){
327 if(getCellDistance(myCell_l, retreatIt_l) < retreatDistance_l){
328 retreatDistance_l = getCellDistance(myCell_l, retreatIt_l);
329 targetRetreat_l = retreatIt_l;
333 moveTowardCell(targetRetreat_l);
334 debug("<<< moveAfter()");
341 //si defi lance par ennemi,
344 debug("[count] init:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
345 var nameNearest_l = getName(getNearestEnemy());
346 if(LEVEL_G >= 14 && getFightContext() === FIGHT_CONTEXT_CHALLENGE
348 && !(nameNearest_l == "LeekSkinteur"
349 || nameNearest_l == "LeekHeFacteur"
350 || nameNearest_l == "LessCrabouilleur"
351 || nameNearest_l === "pibourrin"
352 || nameNearest_l === "poirTouz"
353 || nameNearest_l === "poirTage"
354 || nameNearest_l === "Marie75"
355 || nameNearest_l === "Marie75001")){
356 var enemy = getNearestEnemy();
358 moveTowardCell(getCellToUseWeapon(enemy));
365 debug("[count] shoot:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
369 debug("[count] moveAfter:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
373 debug("[count] end:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);