proprification securite et estimation complexite
[multileek.git] / src / test__5639.lks
blob5f979fc01b9dcca6af2bd6a73b04ec679d6cc9aa
1 // NAME : IA_Exemple
2 // DEFINITION : main
3 //
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 = [];
42 function init(){
43 debug(">>> init()");
45         TURN_G++;
46         if(!IS_INITED_G) {
47                 initObstaclesEnemiesAlliesPositions();
48                 initLeeksCarac();
49                 debug("LEEKS_CONSTANT_CARAC_G = " + LEEKS_CONSTANT_CARAC_G);
50         }
51         initLeeksCaracTurn();
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();
58         if(!IS_INITED_G){
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);
66                         }
67                 }
68                 setWeapon(currentWeaponSelected_l);
70                 IS_INITED_G = true;
71         }
72 debug("<<< init()");
77 function end(){
78 debug(">>> end()");
80         WEAKEST_ENEMY_G = getWeakestAliveEnemy();
81 debug("<<< end()");
86 function fire(item_p, cell_p, leek_p){
87 debug(">>> fire(" + getItemName(item_p) + ", " + cell_p + ", " + getName(leek_p) + ")");
89         var cellLeek_l = -1;
90         if(LEVEL_G >= 5) {
91                 cellLeek_l = getCell(leek_p);
92         }
93         if(isWeapon(item_p)){
94                 if(getWeapon() !== item_p){
95                         setWeapon(item_p);
96                 }
97                 if(cell_p !== null && cell_p < 612 && cell_p >= 0){
98                         useWeaponOnCell(cell_p);
99                 }else{
100                         useWeapon(leek_p);
101                 }
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;
105                 }
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;
109                         }
110                 }else{
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;
113                         }
114                 }
115         }
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);
122                 }
123         }
124         if(enemyWasKilled_l){
125                 WEAKEST_ENEMY_G = getWeakestAliveEnemy();
126                 updateReachableCells();
127         }
128 debug("<<< fire(" + getItemName(item_p) + ", " + cell_p + ", " + getName(leek_p) + ")");
132 function shoot(){
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]);
138                 if(score_l > 0){
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;
143                         }
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){
149                                         damageME_l = 0;
150                                 }
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);
154                                         }
155                                         if(reachableCell_l !== getCell()){
156                                                 moveToCell(reachableCell_l, 1);
157                                                 updateReachableCells();
158                                         }
159                                         while(canShootBasic(ME_G, item_l)){
160                                                 fire(item_l, targetCell_l, WEAKEST_ENEMY_G);
161                                         }
162                                 }
163                         }
164                 }
165         }
166 debug("<<< shoot()");
171 global COEF_ESTIMATD_COMPLEXITY_G = 8;
172 global MIN_SECURITY_INSTRUCTION_G = 25000;
173 function retreat(){
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;
183                                         if(LEVEL_G >= 36){
184                                                 if(isChip(item_l) && getCooldown(item_l, enemy_l) > 1){
185                                                         probaCooldownOK_l = 0;
186                                                 }
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];
190                                         }
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++;
194                                 }
195                         }
196                 }
197         }
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;
203         }
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;
214                 }
215                 if(INSTRUCTIONS_LIMIT - getInstructionsCount() < securityInstructions_l){
216                         break;
217                 }
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);
225                                         break;
226                                 }
227                         }
228                 }
229                 if(count(currentRetreatCells) > 0){
230                         retreatCells_l = currentRetreatCells;
231                 }
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);
240                 }else{
241                         debug("nbInstructions_l = " + nbInstructions_l + " and estimationQuality_l = " + estimationQuality_l);
242                 }
243         }
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){
250                 if(LEVEL_G > 5
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;
256                 }
257         }
258         for(var pathCell_l in REACHABLE_CELLS_G[targetCell_l][0]){
259                 moveToCell(pathCell_l, 1);
260         }
261         if(targetCell_l !== getCell()){
262                 moveToCell(targetCell_l, 1);
263         }
267 function moveAfter(){
268 debug(">>> moveAfter()");
270         if(LEVEL_G < 5){
271 debug("<<< moveAfter()");
272                 return;
273         }
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 + "]");
278         var targetRetreat_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)
285                 {
286                         moveAwayFrom(getNearestEnemy());
287                         debug("enemy same place?!");
288 debug("<<< moveAfter()");
289                         return;
290                 }
291                 if(getMP() == 0)
292                 {
293                         debug("no more MP");
294 debug("<<< moveAfter()");
295                         return;
296                 }
298                 if(abs(xDirectionEnemy_l) > abs(yDirectionEnemy_l)){
299                         if(yDirectionEnemy_l == 0)
300                         {
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());
304                                 }
305                         }else{
306                                 targetRetreat_l = getCellFromXY(xMe_l, yMe_l - signum(yDirectionEnemy_l)*getMP());
307                         }
308                 }else{
309                         if(xDirectionEnemy_l == 0)
310                         {
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);
314                                 }
315                         }else{
316                                 targetRetreat_l = getCellFromXY(xMe_l - signum(yDirectionEnemy_l)*getMP(), yMe_l);
317                         }
318                 }
319         }
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;
330                         }
331                 }
332         }
333         moveTowardCell(targetRetreat_l);
334 debug("<<< moveAfter()");
339 //----- main -----
341 //si defi lance par ennemi,
342 //actions de base
343 init();
344 debug("[count] init:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
345 var nameNearest_l = getName(getNearestEnemy());
346 if(LEVEL_G >= 14 && getFightContext() === FIGHT_CONTEXT_CHALLENGE
347                 && isEnemy(0)
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();
357         if(LEVEL_G >= 5){
358                 moveTowardCell(getCellToUseWeapon(enemy));
359         }else{
360                 moveToward(enemy);
361         }
362         useWeapon(enemy);
363 }else{
364         //shoot();
365         debug("[count] shoot:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
367         retreat();
368         //moveAfter();
369         debug("[count] moveAfter:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);
372         end();
373         debug("[count] end:" + getInstructionsCount() +"/"+ INSTRUCTIONS_LIMIT);