2000/def2.r

001/******************************************************************************
002  CRobot DEF2.R
003 
004  Creato nel Ottobre 2000 per il Torneo di IOPROGRAMMO
005 
006  Massimo Paradisi
007 
008 
009  Il Robot si posiziona nell'angolo pi� vicino e si muove rapidamente in
010  oscillazione orizzontale e verticale (a L).
011  Ogni 1500 cicli circa, fa uno scan per vedere quanti nemici sono rimasti.
012  Se ne � rimasto solo uno, attacca disegnando un quadrilatero casuale (routine
013  di kill!) in base alla posizione che ha al momento dirigendosi per 45�, 135�, 225� 315�,
014  sparando con la routine di goblin in movimento.
015*****************************************************************************/
016int deg,odeg;      /* gradi dove fa lo scan*/
017int range,orange;  /* distanza del target */
018int dir;           /* direzione su cui si muove il robot*/
019int quad;          /* n. di quadrante in cui sta oscillando */
020int cc;            /* contatore di cicli */
021int od;            /* memorizza l'ultimo valore di damage()*/
022int corrx,corry;   /* correttivo usato per l'oscillazione nella parte W o E */
023int x,y;           /* memorizzano il valore di loc_x e loc_y */
024 
025main()
026{
027 
028    /*
029    il robot si muove oscillando eseguendo in continuazione la routine
030    di fuoco
031    Se � rimasto un solo nemico, lancia la fase ONLYONE
032    */
033 
034    /* 1  cc = circa 120 cicli
035       10 cc = circa 1200 cicli
036       17 cc = circa 2000 cicli*/
037 
038    quad=0;
039    pos_ini();
040    vai();
041    deg=1;
042 
043        if(quad==1)
044        {
045            while(1)
046            {
047            cc+=1;
048            runalto();
049            runsinistra();
050            if(cc>15) radar();
051            rundestra();
052            runbasso();
053            }
054        }
055        else if(quad==2)
056        {
057            while(1)
058            {
059            cc+=1;
060            runalto();
061            rundestra();
062            if(cc>15) radar();
063            runsinistra();
064            runbasso();
065            }
066        }
067        else if(quad==3)
068        {
069            while(1)
070            {
071            cc+=1;
072            runbasso();
073            rundestra();
074            runsinistra();
075            if(cc>15) radar();
076            runalto();
077            }
078        }
079        else if(quad==4)
080        {
081            while(1)
082            {
083            cc+=1;
084            runbasso();
085            runsinistra();
086            rundestra();
087            if(cc>15) radar();
088            runalto();
089            }
090        }
091 
092}
093 
094/* Decide il quadrante pi� vicino in cui posizionarsi*/
095pos_ini()
096{
097x=loc_x();
098y=loc_y();
099if(y>500 && x>500) quad=1;
100else if(y>500 && x<501) quad=2;
101else if(y<501 && x<501) quad=3;
102else quad=4;
103corrx=799*(quad==1 || quad==4);
104corry=799*(quad==1 || quad==2);
105}
106 
107/* Posiziona il robot nel quadrante indicato da QUAD */
108vai()
109    {
110    /* la direzione � calcolata in base al quadrante dove si trova*/
111    return;
112    dir = 90+180*(quad==3 || quad==4);
113    if(dir==90)
114        while(loc_y() <930) shoot();
115    else
116        {
117        while(loc_y() >070) shoot();
118        }
119    while(speed()>49) drive(dir,49);
120    }
121 
122/* scanna per due giri l'arena per verificare quanti nemici ci sono
123   ritorna 1, se c'e' un solo nemico */
124 
125radar()
126{
127    int dd,t;
128    drive(dir,0);
129    dd=-10; t=0;
130    while((dd+=20)!=710) if (scan(dd,10)) ++t;
131    if(t<3)
132        onlyone();
133        cc=1;
134    return 1;
135}
136 
137shoot()
138{
139drive(dir,100);
140  if( (range=scan(deg,10)) && (range<700) )
141    {
142          if (scan(deg+353,3)) cannon(deg+=353,(scan(deg,10)<<1)-range);
143     else if (scan(deg+7,  3)) cannon(deg+=7,  (scan(deg,10)<<1)-range);
144     else if (scan(deg,   10)) cannon(deg,     (scan(deg,10)<<1)-range);
145     else shoot2();
146    }
147   else shoot2();
148}
149shoot2()
150{
151 
152   if (range=scan(deg+340,10)) cannon(deg+=340,(scan(deg,10)<<1)-range);
153   else if (range=scan(deg+20, 10)) cannon(deg+=20 ,(scan(deg,10)<<1)-range);
154   else if (range=scan(deg+320,10)) cannon(deg+=320,(scan(deg,10)<<1)-range);
155   else if (range=scan(deg+40, 10)) cannon(deg+=40 ,(scan(deg,10)<<1)-range);
156   else if (range=scan(deg+300,10)) cannon(deg+=300,range);
157   else if (range=scan(deg+60, 10)) cannon(deg+=60 ,range);
158   else deg+=140;
159}
160 
161 
162runsinistra()
163{
164    /* vai verso sinistra e spara*/
165    dir = 180;
166    while (loc_x() > (101+corrx)) shoot();
167}
168runalto()
169{
170    /* vai verso altro e spara*/
171    dir = 90;
172    while (loc_y() < (101+corry)) shoot();
173}
174runbasso()
175{
176    /* vai verso altro e spara*/
177    dir = 270;
178    while (loc_y() > (101+corry)) shoot();
179}
180rundestra()
181{
182    /* vai verso altro e spara*/
183    dir = 0;
184    while (loc_x() < (101+corrx)) shoot();
185}
186 
187onlyone()
188{
189 
190   while(1)
191   {
192       while(loc_y()<850 && quad<=1)
193       {
194          dir=135;
195          fire();
196       }
197       while(loc_x()>150 && quad<=2)
198       {
199          dir=225;
200          fire();
201       }
202       while(loc_y()>150 && quad<=3)
203       {
204          dir=315;
205          fire();
206       }
207       while(loc_x()<850 && quad<=4)
208       {
209          dir=45;
210          fire();
211       }
212       quad=0;
213   }
214}
215 
216fire()
217{
218    drive(dir,100);
219    if (orange=scan(deg,10))
220    {
221        if (!scan(deg-=5,5)) deg+=10;
222        if (orange>700)
223        {
224            if (!scan(deg-=3,3)) deg+=6;
225            cannon(deg,orange); deg+=40; return;
226        }
227 
228        if(scan(deg-5,1)) deg-=5;
229        if(scan(deg+5,1)) deg+=5;
230        if(scan(deg-3,1)) deg-=3;
231        if(scan(deg+3,1)) deg+=3;
232        if(scan(deg-1,1)) deg-=1;
233        if(scan(deg+1,1)) deg+=1;
234 
235        if (orange=scan(odeg=deg,5))
236        {
237            if(scan(deg-5,1)) deg-=5;
238            if(scan(deg+5,1)) deg+=5;
239            if(scan(deg-3,1)) deg-=3;
240            if(scan(deg+3,1)) deg+=3;
241            if(scan(deg-1,1)) deg-=1;
242            if(scan(deg+1,1)) deg+=1;
243 
244            if (range=scan(deg,10))
245                cannon(deg+(deg-odeg)*((1200+range)>>9)-(sin(deg-dir)>>14),
246                       range*160/(160+orange-range-(cos(deg-dir)>>12)));
247        }
248     }
249     else
250     {
251        if (scan(deg-=20,10)) return;
252        if (scan(deg+=40,10)) return;
253        deg+=40; return;
254     }
255}