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 | **------------------------------------------------------------------*/ |
014 | int STOP; /* motore fermo */ |
015 | int MAXVEL; /* motore al massimo */ |
016 | int MAXVELCD; /* max. velocita' per poter cambiare direzione */ |
017 | int DIM_XY; /* numero di caselle orizzontali/verticali */ |
018 | int MARGMURO; /* margine di sicurezza per il muro */ |
019 | int MAXTIRO; /* massima lunghezza di tiro del cannone */ |
020 | int MINTIRO; /* minima lunghezza di tiro del cannone */ |
021 | int AMPSCAN; /* ampiezza dell' angolo di scansione */ |
022 | int INCRSCAN; /* incremento nell' angolo di scansione */ |
023 | int RIPSCAN; /* numero scansioni consecutive */ |
024 |
025 | /*------------------------------------------------------------------** |
026 | ** VARIABILI GLOBALI ** |
027 | **------------------------------------------------------------------*/ |
028 | int AngScan; /* ultimo angolo di scansione del radar */ |
029 | int DirMarcia; /* direzione (angolo) attuale di marcia */ |
030 | int AutoPilota; /* autopilota in funzione (tranquilli...) */ |
031 | int Tranquillo; /* flag per verificare se sono al sicuro */ |
032 |
033 | /*------------------------------------------------------------------** |
034 | ** INIZIALIZZA LE COSTANTI E LE VARIABILI GLOBALI ** |
035 | **------------------------------------------------------------------*/ |
036 | inizializza() |
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 | **------------------------------------------------------------------*/ |
049 | abs (num) |
050 | int 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 | **------------------------------------------------------------------*/ |
059 | direzione(old_x,old_y,new_x,new_y) |
060 | int 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 | **------------------------------------------------------------------*/ |
082 | go_dir(direzione,vel) |
083 | int direzione; |
084 | int 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 | **------------------------------------------------------------------*/ |
115 | go_to(x,y,vel) |
116 | int 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 | **------------------------------------------------------------------*/ |
126 | testmarg(x,y) |
127 | int 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 | **------------------------------------------------------------------*/ |
146 | distanza(x1,y1,x2,y2) |
147 | int 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 | *********************************************************************/ |
158 | main() |
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 | **------------------------------------------------------------------*/ |
170 | loop() |
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 | **------------------------------------------------------------------*/ |
179 | spara() |
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 | **------------------------------------------------------------------*/ |
212 | ver_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 | } |