1996/ap_4.r

001/*
002**
003**           ap_4.r            
004**             di              
005**       Antonio Pennino       
006**     (MC4366@mclink.it)      
007**          30/09/95           
008**
009*/
010 
011/*------------------------------------------------------------------**
012**               PRINCIPALI COSTANTI DEL PROGRAMMA                  **
013**------------------------------------------------------------------*/
014int  STOP;          /*  motore fermo                                */
015int  MAXVEL;        /*  motore al massimo                           */
016int  MAXVELCD;      /*  max. velocita' per poter cambiare direzione */
017int  DIM_XY;        /*  numero di caselle orizzontali/verticali     */
018int  MARGMURO;      /*  margine di sicurezza per il muro            */
019int  MAXTIRO;       /*  massima lunghezza di tiro del cannone       */
020int  MINTIRO;       /*  minima  lunghezza di tiro del cannone       */
021int  AMPSCAN;       /*  ampiezza dell' angolo di scansione          */
022int  INCRSCAN;      /*  incremento nell' angolo di scansione        */
023int  RIPSCAN;       /*  numero scansioni consecutive                */
024 
025/*------------------------------------------------------------------**
026**                      VARIABILI GLOBALI                           **
027**------------------------------------------------------------------*/
028int  AngScan;       /*  ultimo angolo di scansione del radar        */
029int  DirMarcia;     /*  direzione (angolo) attuale di marcia        */
030int  AutoPilota;    /*  autopilota in funzione (tranquilli...)      */
031int  Tranquillo;    /*  flag per verificare se sono al sicuro       */
032 
033/*------------------------------------------------------------------**
034**          INIZIALIZZA LE COSTANTI E LE VARIABILI GLOBALI          **
035**------------------------------------------------------------------*/
036inizializza()
037{
038  STOP=0;      MAXVEL=100;         MAXVELCD=40;
039  DIM_XY=1000; MARGMURO=240;
040  MAXTIRO=700; MINTIRO=50; 
041  AMPSCAN=9;   INCRSCAN=AMPSCAN*2; RIPSCAN=5;     
042   
043  AngScan=0;   AutoPilota=0;       Tranquillo=0;
044}
045 
046/*------------------------------------------------------------------**
047**         RESTITUISCO IL VALORE ASSOLUTO (>0) DI UN INTERO         **
048**------------------------------------------------------------------*/
049abs(num)
050int num;
051{
052  if (num>=0) return(num); else return(num*-1);
053}
054 
055/*------------------------------------------------------------------**
056**        CALCOLO LA DIREZIONE PER ANDARE IN UN CERTO PUNTO         **
057**   L' angolo e' restituito normalizzato ( 0 <= angolo < 360 )     **
058**------------------------------------------------------------------*/
059direzione(old_x,old_y,new_x,new_y)
060int old_x,old_y,new_x,new_y;
061{
062  int dx,dy,angolo;                 /* dichiaro le variabili locali */      
063  dx=new_x-old_x; dy=new_y-old_y;   /* calcolo le differenze in X,Y */
064  if (dx==0)                        /* valuto se direzione verticale*/
065    if(dy>=0) return(90);           /* ... new_y e' a +90 gradi     */
066     else return(270);          /* ... new_y e' a -90 gradi     */
067  angolo=atan((100000*dy)/abs(dx)); /* calcolo l' angolo(1,4 quadr.)*/
068  if ( dx < 0 ) angolo=180-angolo;  /* corr. x secondo e terzo quad.*/
069  angolo=(angolo+720)%360;          /* normalizzo l' angolo (0-359) */
070  return(angolo);                   /* restituisco l' angolo        */
071}
072 
073/*------------------------------------------------------------------**
074**               SI SPOSTA NELLA DIREZIONE SPECIFICATA              **
075**               con correzione per evitare il margine              **
076**  -------------------------------------------------------------   **
077**          ( direzione , velocita ; DirMarcia , AutoPilota )       **
078**  _____________________________________________________________   **
079**  AutoPilota ON significa che si e' ai bordi ma che l' angolo e'  **
080**  stato preventivamente controllato (non rischio impatto bordi)   **  
081**------------------------------------------------------------------*/
082go_dir(direzione,vel)
083int direzione;
084int vel;
085{
086  int x,y,amin,amax,minc,maxc;      /* angoli e coordinate min/max  */
087   
088  drive (DirMarcia,MAXVELCD);     /* mi porto avanti con la manovra */
089 
090  x=loc_x(); y=loc_y(); minc=MARGMURO; maxc=DIM_XY-MARGMURO;
091  amin=0; amax=360;                           /* default a. min/max */
092  AutoPilota=0;                               /* default AutoPilota */
093   
094  if (x<minc && y<minc) { amin=0;   amax=90;  } /* basso a sinistra */
095  if (x<minc && y<minc) { if (direzione>180) direzione-=360; }
096  if (x>maxc && y<minc) { amin=90;  amax=180; } /* basso a destra   */
097  if (x<minc && y>maxc) { amin=270; amax=360; } /* alto  a sinistra */
098  if (x>maxc && y>maxc) { amin=180; amax=270; } /* alto  a destra   */
099 
100  if (!(direzione>=amin && direzione<=amax))    /* ____CORREGGO____ */
101    if (abs(direzione-amin) < abs(direzione-amax))
102         { direzione=amin; AutoPilota=1; }      /* _AutoPilota ON _ */
103    else { direzione=amax; AutoPilota=1; }      /* _AutoPilota ON _ */
104  
105  drive (DirMarcia=direzione,vel);
106  while (speed() == STOP)     drive(DirMarcia,vel) ;
107  while (testmarg(-1,-1) > 1) ;
108  return(DirMarcia);
109}
110 
111/*------------------------------------------------------------------**
112**              SI SPOSTA NELLA LOCAZIONE SPECIFICATA               **
113**                ( x , y , velocita ; DirMarcia )                  **
114**------------------------------------------------------------------*/
115go_to(x,y,vel)
116int x,y,vel;
117{
118  return( go_dir( DirMarcia=direzione(loc_x(),loc_y(),x,y) , vel ) );
119}
120 
121/*------------------------------------------------------------------**
122**     VERIFICO SE LA COORDINATA SPECIFICATA SI TROVA AI MARGINI    **
123**     Se la coordinata e' -1,-1 allora uso la attuale coordinata   **
124**              ( 0=falso, 1=su un lato, 2=in un angolo )           **
125**------------------------------------------------------------------*/
126testmarg(x,y)
127int x,y;
128{
129  int ritorno, diffmuro;
130   
131  diffmuro=DIM_XY-MARGMURO; ritorno=0;
132  if (x==-1 && y==-1) { x=loc_x(); y=loc_y(); }
133 
134  if (x<MARGMURO)         ++ritorno;
135  if (y<MARGMURO)         ++ritorno;
136  if (x>diffmuro)         ++ritorno;
137  if (y>diffmuro)         ++ritorno;
138 
139  return(ritorno);
140}
141 
142/*------------------------------------------------------------------**
143**                 CALCOLA LA DISTANZA TRA DUE PUNTI                **
144**                    ( x1,y1,x2,y2 ; distanza )                    **
145**------------------------------------------------------------------*/
146distanza(x1,y1,x2,y2)
147int x1,y1,x2,y2;
148{
149  int dx,dy;
150  dx=x1-x2; dy=y1-y2;
151  return( sqrt(dx*dx+dy*dy) );
152}
153 
154 
155/*********************************************************************
156**                 I N I Z I O   P R O G R A M M A                  **
157*********************************************************************/
158main()
159{
160  inizializza();
161  go_to(0,0,MAXVEL);
162  while(1) loop();
163
164 
165/*------------------------------------------------------------------**
166**      LOOP, privilegiando il controllo dei bordi e solo in        **
167**      seconda battuta le operazioni di sparo (se mi accorgo       **
168**      che sono fermo od in un angolo, esco subito!)               **
169**------------------------------------------------------------------*/
170loop()
171{
172  if ( ver_tranq() )  spara(); else go_dir(DirMarcia,MAXVEL);
173}
174 
175/*------------------------------------------------------------------**
176**                        Routine di SPARO!!                        **
177**       Anche qui' dentro esco alla svelta se sono nei guai!       **
178**------------------------------------------------------------------*/
179spara()
180{
181  int i,d;                                    /* i=loop, d=distanza */
182   
183  d=0;                          /* parto fiducioso... e' tutto Ok!? */
184  while(Tranquillo)             /* tanto controllo piu' in la'...   */
185    {                           /* d=0 --> non ho il bersaglio      */
186     i=RIPSCAN+1;
187     while ( Tranquillo && (--i >= 0) )          /* verifica & LOOP */
188       {
189    AngScan=AngScan+INCRSCAN+180;    /* imposto il nuovo angolo */
190    while ( ver_tranq() && (d=scan(AngScan,AMPSCAN)) )
191      {
192       int a1,a2;
193       if ( (d>MINTIRO) && (d<=MAXTIRO) ) cannon(AngScan,(d*8)/9);
194       a1=AngScan-INCRSCAN;
195       a2=AngScan+INCRSCAN;
196       if      (d=scan(a1,AMPSCAN)) AngScan=a1;
197       else if (d=scan(a2,AMPSCAN)) AngScan=a2;
198      }
199       }
200    }
201}
202 
203/*------------------------------------------------------------------**
204**          Posso stare tranquillo, oppure sto rischiando?          **
205**     ----------------------------------------------------------   **
206**     Se sono nei guai DISATTIVO l' autopilota e segnalo "guai",   **
207**     cosi' come nel caso risulti non piu' necessario (in centro)  **
208**     Altrimenti la posizione dell' autopilota rimane invariata    **
209**     ----------------------------------------------------------   **
210**          ( 0=falso (guai!), 1=vero (cioe' tranquillo) )          **
211**------------------------------------------------------------------*/
212ver_tranq() 
213{
214  int t;
215  t=testmarg(-1,-1);
216  if (speed()==0)           { Tranquillo=0; AutoPilota=0; return Tranquillo; }
217  if (t==2)                 { Tranquillo=0; AutoPilota=0; return Tranquillo; }
218  if (t==1 && AutoPilota==0){ Tranquillo=0;               return Tranquillo; }
219  if (t==1 && AutoPilota==1){ Tranquillo=1;               return Tranquillo; }
220  if (t==0)                 { Tranquillo=1; AutoPilota=0; return Tranquillo; }
221  return(Tranquillo=1);                    
222}