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 itemEnemyDistanceDanger_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 for(var distance_l = 0; distance_l <= STUFFS_G[item_l][STUFF_RADIUS_G]; distance_l++){
192 push(itemEnemyDistanceDanger_l, [item_l, enemy_l, distance_l]);
193 scoreTable_l[itemEnemyDangerIt_l] = getNbAttackComplete(enemy_l, item_l) * probaCooldownOK_l * expectedDamage(enemy_l, item_l, ME_G, distance_l);
194 itemEnemyDangerIt_l++;
200 assocSort(scoreTable_l, SORT_DESC);
201 updateReachableCells();
202 var retreatCells_l = [];
203 for(var cellIt_l : var pathIt_l in REACHABLE_CELLS_G){
204 retreatCells_l[cellIt_l] = 1;
206 var previousEnemy_l = -1;
207 var mapItemMapEnemyNoHiding_l = [];
208 for(itemEnemyDangerIt_l : var score_l in scoreTable_l) {
209 var nbInstructionBeginItemScore_l = getInstructionsCount();
210 var enemy_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][1];
211 var cellsReachablebleEnemy_l = getReachableCellCloseToMe(LEEK_MOVEMENTS_G[enemy_l][TURN_G], LEEKS_VARIABLE_CARAC_G[enemy_l][TURN_G][CARAC_MP]);
212 var estimatedComplexity_l = count(cellsReachablebleEnemy_l) * count(retreatCells_l) * COEF_ESTIMATD_COMPLEXITY_G;
213 var securityInstructions_l = MIN_SECURITY_INSTRUCTION_G;
214 if(estimatedComplexity_l > securityInstructions_l){
215 securityInstructions_l = estimatedComplexity_l;
217 if(INSTRUCTIONS_LIMIT - getInstructionsCount() < securityInstructions_l){
221 var item_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][0];
222 if(mapItemMapEnemyNoHiding_l[item_l] !== null
223 && mapItemMapEnemyNoHiding_l[item_l][enemy_l] !== null){
226 var distance_l = itemEnemyDistanceDanger_l[itemEnemyDangerIt_l][2];
227 var currentRetreatCells = retreatCells_l;
228 //on elimine les cellules dangereuses
230 var outEdge_l = getDistantBorder(retreatCells_l, distance_l);
231 for(var hurtableCellMe_l : var cellsProducingIt_l in outEdge_l[distance_l - 1]){
232 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
233 if(mightShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, hurtableCellMe_l, ME_G)){
234 var cellsToRemove_l = [];
235 push(cellsToRemove_l, hurtableCellMe_l);
236 for(var itDist_l = 0; itDist_l < distance_l; itDist_l++){
237 var newCellsToRemove_l = [];
238 for(var itCellCurrentBorder in cellsToRemove_l){
239 pushAll(newCellsToRemove_l, outEdge_l[distance_l - 1 - itDist_l][itCellCurrentBorder]);
241 cellsToRemove_l = newCellsToRemove_l;
243 for(var cellIt_l in cellsToRemove_l){
244 removeKey(currentRetreatCells, cellIt_l);
248 if(count(currentRetreatCells) == 0){
252 if(count(currentRetreatCells) == 0){
257 for(var reachableCellMe_l : var pathMe_l in retreatCells_l){
258 for(var reachableCellEnemy_l : var pathEnemy_l in cellsReachablebleEnemy_l){
259 if(mightShootCellToCell(reachableCellEnemy_l, enemy_l, item_l, reachableCellMe_l, ME_G)){
260 removeKey(currentRetreatCells, reachableCellMe_l);
266 if(count(currentRetreatCells) > 0){
267 retreatCells_l = currentRetreatCells;
269 if(mapItemMapEnemyNoHiding_l[item_l] === null){
270 mapItemMapEnemyNoHiding_l[item_l] = [];
272 mapItemMapEnemyNoHiding_l[item_l][enemy_l] = 1;
275 var nbInstructions_l = getInstructionsCount() - nbInstructionBeginItemScore_l;
276 var estimationQuality_l = nbInstructions_l / estimatedComplexity_l;
277 if(nbInstructions_l > MIN_SECURITY_INSTRUCTION_G && estimationQuality_l > 1){
278 COEF_ESTIMATD_COMPLEXITY_G *= estimationQuality_l;
279 debugE("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". New COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
280 }else if(nbInstructions_l > 0.5 * MIN_SECURITY_INSTRUCTION_G && estimationQuality_l < 0.7){
281 debugW("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
283 debug("nbInstructions_l = " + nbInstructions_l + " and quality = " + estimationQuality_l + ". COEF = " + COEF_ESTIMATD_COMPLEXITY_G);
287 var distanceWeakest_l = 10000;
288 var distanceCenter_l = 10000;
289 var targetCell_l = 306;
290 var weakestCell_l = LEEK_MOVEMENTS_G[WEAKEST_ENEMY_G][TURN_G];
291 for(var cellIt_l : var distanceEnemyIt_l in retreatCells_l){
292 var distanceEnemy_l = 0;
293 if(weakestCell_l !== null){
294 distanceEnemy_l = getPathLength(cellIt_l, weakestCell_l);
297 && ((distanceEnemy_l < distanceWeakest_l)
298 ||(distanceEnemy_l == distanceWeakest_l && getCellDistance(cellIt_l, 306) < distanceCenter_l))){
299 distanceWeakest_l = distanceEnemy_l;
300 distanceCenter_l = getCellDistance(cellIt_l, 306);
301 targetCell_l = cellIt_l;
304 for(var pathCell_l in REACHABLE_CELLS_G[targetCell_l][0]){
305 moveToCell(pathCell_l, 1);
307 if(targetCell_l !== getCell()){
308 moveToCell(targetCell_l, 1);
313 function moveAfter(){
314 debug(">>> moveAfter()");
317 debug("<<< moveAfter()");
320 var myCell_l = getCell();
321 var xMe_l = getCellX(myCell_l);
322 var yMe_l = getCellY(myCell_l);
323 debug("me = [" + xMe_l + "; " + yMe_l + "]");
325 var cellEnemy_l = getCell(getNearestEnemy());
326 if(cellEnemy_l !== null && cellEnemy_l != -1){
327 debug("enemy = [" + getCellX(cellEnemy_l) + "; " + getCellY(cellEnemy_l) + "]");
328 var xDirectionEnemy_l = getCellX(cellEnemy_l) - xMe_l;
329 var yDirectionEnemy_l = getCellY(cellEnemy_l) - yMe_l;
330 if(abs(xDirectionEnemy_l) + abs(yDirectionEnemy_l) == 0)
332 moveAwayFrom(getNearestEnemy());
333 debug("enemy same place?!");
334 debug("<<< moveAfter()");
340 debug("<<< moveAfter()");
344 if(abs(xDirectionEnemy_l) > abs(yDirectionEnemy_l)){
345 if(yDirectionEnemy_l == 0)
347 targetRetreat_l = getCellFromXY(xMe_l, yMe_l + getMP());
348 if(targetRetreat_l === null || targetRetreat_l == -1){
349 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - getMP());
352 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - signum(yDirectionEnemy_l)*getMP());
355 if(xDirectionEnemy_l == 0)
357 targetRetreat_l = getCellFromXY(xMe_l + getMP(), yMe_l);
358 if(targetRetreat_l === null || targetRetreat_l == -1){
359 targetRetreat_l = getCellFromXY(xMe_l - getMP(), yMe_l);
362 targetRetreat_l = getCellFromXY(xMe_l - signum(yDirectionEnemy_l)*getMP(), yMe_l);
367 if(targetRetreat_l === null || targetRetreat_l == -1){
368 debug("retraite nulle");
369 //on vise le centre d'un cote du terrain le plus proche
370 var possibleRetreats_l = [26, 298, 314, 598];
371 var retreatDistance_l = 9999;
372 for(var retreatIt_l in possibleRetreats_l){
373 if(getCellDistance(myCell_l, retreatIt_l) < retreatDistance_l){
374 retreatDistance_l = getCellDistance(myCell_l, retreatIt_l);
375 targetRetreat_l = retreatIt_l;
379 moveTowardCell(targetRetreat_l);
380 debug("<<< moveAfter()");
387 //si defi lance par ennemi,
390 debug("[count] init:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
391 var nameNearest_l = getName(getNearestEnemy());
392 if(LEVEL_G >= 14 && getFightContext() === FIGHT_CONTEXT_CHALLENGE
394 && !(nameNearest_l == "LeekSkinteur"
395 || nameNearest_l == "LeekHeFacteur"
396 || nameNearest_l == "LessCrabouilleur"
397 || nameNearest_l === "pibourrin"
398 || nameNearest_l === "poirTouz"
399 || nameNearest_l === "poirTage"
400 || nameNearest_l === "Marie75"
401 || nameNearest_l === "Marie75001")){
402 var enemy = getNearestEnemy();
404 moveTowardCell(getCellToUseWeapon(enemy));
411 debug("[count] shoot:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
415 debug("[count] moveAfter:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
419 debug("[count] end:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);