2010/enkidu.r

001/*
002 
003Torneo midi 2010
004 
005Enkidu.r ver.1.25 del 12-marzo-2010
006Riesumato alla circolazione da Marco Borsari,
007per incidenti rivolgersi all'ufficio Antica Babilonia.
008 
009Scheda tecnica (liberamente tratto):
010Il robot e' un discendente diretto della famiglia di KakakaTz e
011iLbEsTiO, alle cui note esplicative si rimanda, costituendone
012una fusione. Innanzitutto il codice e' stato reso piu' leggibile
013eliminando i cortocircuiti piu' strani e recuperando lo spazio perso
014raccogliendo i brani piu' adatti. Durante questo passaggio, sono stati
015corretti alcuni piccoli errori (almeno presunti tali) nelle direzioni
016di frenata e nella sequenza if-else della routine di disturbo negli
017angoli adiacenti. La modifica principale alla strategia risiede nello
018spostamento delle oscillazioni corte nel caso appena descritto (il cui
019comportamento e' stato reso piu' impavido) per integrarle con il
020cambio di angolo difensivo, ora infatti se Enk. subisce dei danni ma
021il nemico si trova lontano, preferisce rimanere dove si trova a
022ciondolare alcune volte alternando i due assi. Questo nel tentativo di
023distogliere da se stesso le malefiche attenzioni ed evitare di andare
024a cacciarsi in guai peggiori. Inoltre nella routine di attacco f2f e'
025stato aggiunto un controllo sulla variazione dell'angolo sulla
026falsariga di quello presente in Satana (altra vecchia conoscenza), ed
027e' stata tolta l'opzione cautelativa quando le condizioni siano
028critiche, se si e' in ballo bisogna ballare. I parametri delle
029scansioni nelle routine di fuoco sono stati ricalibrati, ho anche
030invertito nella Toxica il peso della correzione sull'angolo,
031nell'assunto che esso abbia maggiore rilevanza a corta distanza. Il
032risultato non e' sempre positivo ma comunque mai peggiore, in ogni
033modo sembra avere maggiore efficacia contro quegli avversari che
034oscillano molto stretto.
035 
036*/
037 
038int oldang,oldrng,ang,range; /* angolo e distanza dell'avversario          */
039int dir;                     /* direzione in cui camminare                 */
040int clock,disturbo,cambio;   /* clock vale sempre 0 o 1, disturbo          */
041                             /* e' la distanza a cui arrivare a rompere le */
042                             /* scatole e cambio serve per contare i robot */
043                             /* nell'arena                                 */
044int sopra,destra;            /* posizione nell'arena (valore 0 o 1)        */
045int attacco,flag;            /* attacco puo' valere 0 o 1 e flag e' un     */
046                             /* contatore                                  */
047 
048/******************************************/
049/*                                        */
050/* Procedura Principale                   */
051/*                                        */
052/* Difesa ed Attacco                      */
053/*                                        */
054/******************************************/
055 
056main() {
057  int danni,soglia,dir2;     /* danni    = % danni subiti               */
058                             /* soglia   = tolleranza al dolore         */
059                             /* dir2     = variabile d'appoggio per dir */
060 
061  /* va' all'angolino piu' vicino */
062 
063  ang=360;
064  attacco=clock=disturbo=0;
065  vai(180*(loc_x()<500));
066  vai(270-180*(loc_y()>500));
067  cambio=5;
068  soglia=4;
069 
070  /* ciclo principale              */
071  /* - pausa nell'angolino         */
072  /* - oscillazioni d'attacco in 3 */
073  /* - manovra evasiva             */
074  /* e, in caso, attacco finale    */
075 
076  while(1) {
077    danni=damage();
078    while(damage()<danni+soglia) {
079 
080      /* robo-radar           */
081      /* conteggio superstiti */
082      /* nell'arena           */
083 
084      if (cambio>4) {
085        ang=dir+353;
086        cambio=9;
087        flag=24;
088        while(cambio && flag)
089          if (scan(ang+15*((--flag)%8),7)) --cambio;
090        flag=4;
091        if (cambio>=6) {
092          ++attacco;
093          drive(dir,100);
094 
095        /* attacco finale                 */
096        /* in caso di un solo superstite  */
097 
098          while(1) {
099            serpiko(0);
100 
101            /* alla fine ho preferito un controllo */
102            /* sulla distanza (vedi in Frena)      */
103 
104            if (--flag/*flag-=(oldang==ang)+1*/) {
105              if (loc_y()>700) frena(270);
106              else if (loc_y()<300) frena(90);
107                   else if (loc_x()>700) frena(180);
108                        else if (loc_x()<300) frena(0);
109            }
110            else frena(ang+135+90*(clock^=1));
111          }
112        } else if (cambio>=3) {
113 
114        /* disturbo quiete pubblica            */
115        /* (attacco in caso di due superstiti) */
116 
117          ang+=7+90*clock;
118          ++attacco;
119          serpiko(1);
120          if (oldrng)
121            if (oldrng==range || damage()<60) {
122 
123              /* se vedi un robottino simil-statico */
124              /* oppure hai abbastanza energia      */
125              /* attaccalo con una oscillazione     */
126              /* verso di lui                       */
127 
128              disturbo=1500-range;
129              vai(dir2=dir+90*((ang%360)>(dir+45)));
130              serpiko(0);
131              disturbo=0;
132              vai((dir2+180)%360);
133              if (damage()>danni) { danni=damage(); clock^=1; }
134            } else clock^=1;
135          else { danni-=soglia; flag=0; }
136          attacco=0;
137        }
138        cambio=0;
139      }
140      serpiko(1);
141    }
142    if ((!oldrng || oldrng>550) && flag)
143 
144      /* oscilla un poco           */
145      /* (se il nemico e' lontano) */
146 
147      while(--flag) {
148        disturbo=750;
149        vai(dir2=dir+90*clock);
150        disturbo=0;
151        vai((dir2+180)%360);
152        clock^=1;
153      }
154    else
155 
156      /* cambio angolino                  */
157      /* (usato solo in caso di pericolo) */
158 
159      vai(dir+90*(scan(dir+8,10)>scan(dir+82,10)));
160  }
161}
162 
163 
164/******************************************/
165/*                                        */
166/* Procedura Di Cambio Angolino           */
167/* o di Oscillazione in Difesa            */
168/*                                        */
169/******************************************/
170 
171vai(newdir) {
172  int limh1,limh2,liml1,liml2;
173  while(speed()>=50);
174  drive(dir=newdir,100);
175  liml1=(limh1=150+disturbo)-60;     /* limiti x e y per lo spostamento */
176  liml2=(limh2=850-disturbo)+60;     /* e/o oscillazione in attacco a 3 */
177 
178  /* alto           */
179 
180  if (dir==270)      {
181    while(loc_y()>limh1) serpiko(0);
182    if (!disturbo) { drive(dir,60); while(loc_y()>liml1); sopra=0; }
183  }
184 
185  /* basso          */
186 
187  else if (dir==90)  {
188    while(loc_y()<limh2) serpiko(0);
189    if (!disturbo) { drive(dir,60); while(loc_y()<liml2); sopra=1; }
190  }
191 
192  /* sinistra       */
193 
194  else if (dir==180) {
195    while(loc_x()>limh1) serpiko(0);
196    if (!disturbo) { drive(dir,60); while(loc_x()>liml1); destra=0; }
197  }
198 
199  /* destra         */
200 
201  else               {
202    while(loc_x()<limh2) serpiko(0);
203    if (!disturbo) { drive(dir,60); while(loc_x()<liml2); destra=1; }
204  }
205 
206  /* frenata finale */
207 
208  drive(dir,0);
209  dir=180*sopra+90*(sopra^destra);
210}
211 
212 
213/******************************************/
214/*                                        */
215/* Procedura Di Frenata                   */
216/* contro un solo avversario              */
217/*                                        */
218/* Con sparo veloce senza particolari     */
219/* correzioni.                            */
220/*                                        */
221/******************************************/
222 
223frena(newdir) {
224  if (dir!=newdir) {
225    drive(dir,40);                   /* freno                           */
226    while(speed()>=50) {             /* finche' freno sparo (ma veloce) */
227      if (oldrng=scan(ang,10)) {
228        oldang=ang;
229        if (scan(ang+=5,5)); else ang-=10;
230        if (scan(ang+=3,3)); else ang-=6;
231        if (range=scan(ang,10))
232          cannon(ang+(ang-oldang),range+(range-oldrng)*2);
233      } else ang+=85;
234    }
235    drive(dir=newdir,100);           /* riaccelero                      */
236  }
237  if (oldrng<75) flag=4; else flag=2;
238}
239 
240 
241/******************************************/
242/*                                        */
243/* Procedura Di Sparo Preciso             */
244/*                                        */
245/* Con e senza correzione sulla direzione */
246/* in cui si cammina.                     */
247/*                                        */
248/******************************************/
249 
250mira() {
251  if (scan(ang+9,3)) ang+=9;
252  if (scan(ang-9,3)) ang-=9;
253  if (scan(ang+6,2)) ang+=6;
254  if (scan(ang-6,2)) ang-=6;
255  if (scan(ang+3,1)) ang+=3;
256  if (scan(ang-3,1)) ang-=3;
257}
258 
259serpiko(fermo) {
260  if (oldrng=scan(ang,10));                    /* se non sto puntando un nemico          */
261  else if (oldrng=scan(ang-=21,10));           /* ne cerco un'altro                      */
262  else if (oldrng=scan(ang+=42,10));
263  else return (ang+=42);
264  if (oldrng<120) return cannon(ang,oldrng);   /* se e' troppo vicino lo sparo subito    */
265  if (!attacco)                                /* se sto attaccando non cambio obiettivo */
266    if (oldrng>730) { ang+=42; return ++cambio; }
267  if (scan(ang-=5,5)); else ang+=10;           /* affinamento del tiro                   */
268  mira();
269  if (oldrng=scan(oldang=ang,10)) {
270    mira();
271    if (range=scan(ang,10))                    /* sparo con eventuale correzione sulla   */
272                                               /* direzione di movimento                 */
273      cannon(ang+(ang-oldang)*(/*(1200+range)>>9*/(950-range)>>8)-
274        (1-fermo)*(sin(ang-dir)>>14),
275        range*160/(160+oldrng-range-(1-fermo)*(cos(ang-dir)>>12)));
276  }
277}