SCHEDA TECNICA PER II CAMPIONATO C-ROBOTS DI MC
Nome Robot:
Marìka (l'accento sopra la i è significativo)
Autore:
Roberto Ceccarelli
via Covignano 3 - 47037 RIMINI (RN)
tel. 0541/783833
Email: 2:332/[email protected]
Caratteristiche:
Questo robot, scritto e collaudato in meno di una settimana, alla
partenza della battaglia si rintana nell'angolo in alto a sinistra
sparando una serie di raffiche nel tentativo di scacciare un altro
eventuale robot già presente in quella zona.
Una volta installato nell'angolo inizia a scandire un settore di 100
gradi a passi di 20 gradi alla volta, se localizza un bersaglio allora
effettua una scansione fine all'interno dei 20 gradi ed inizia a
sparare ripetendo lo scanning locale fino a che il bersaglio si
allontana o Marìka riporta danni superiori ad una soglia prefissata.
Superata questa soglia di danni il robot si sposta in un altro angolo
(sperando sia più tranquillo) scorrendo lungo il bordo (in modo da
avere le spalle coperte).
Durante lo spostamento effettua uno scanning di copertura su 180 gradi
con le stesse modalità già viste.
Note:
Il fatto di essermi deciso solo all'ultimo momento a partecipare a
questa sfida non mi ha permesso di sviluppare complesse strategie e
nemmeno di eseguire un esauriente collaudo.
Per quanto riguarda la strategia mi sono largamente ispirato a Sniper,
uno degli esempi forniti con il compilatore, del quale ho anche
riportato una routine (come chiaramente indicato nel listato),
migliorandone pero' le capacità di scanning e rendendolo più mobile.
L'ambiente di prova era costituito da Nexus, Jazz (i vincitori delle
scorse edizioni) e da Counter che, anche se sembra incredibile, è uno
dei peggiori nemici di Marìka.
Il problema principale era dovuto al fatto che Marìka girava in senso
antiorario, esattamente come il radar di Counter e quindi una volta
che quest'ultimo lo aveva preso di mira continuava a bombardarlo su
tutto il percorso: invertendo il senso di marcia le cose sono
migliorate; alla fine ho optato per una scelta casuale del verso di
rotazione in modo da cautelarmi maggiormente da questo punto di vista.
Dalle prove effettuate (il mio 486/33 e OS/2 2.0 mi hanno dato una
grossa mano in tal senso) Marìka risulta essere solo leggermente
inferiore a Nexus, mentre straccia regolarmente Jazz.
Con i punteggi del torneo si ottiene una efficienza di circa il 30%,
il che stando alle medie dell'ultima edizione non e' proprio cosa
infima.
Effettivamente i risultati mi sconcertano un po' e sono proprio
curioso di vedere come andrà a finire in ben più ostili campi di
battaglia.
/*
* CASASOFT Mar�ka 1.00
* (c) 1992 Roberto Ceccarelli
* via Covignano 3 - 47037 Rimini (RN)
* tel. 0541/783833
* Email: 2:332/[email protected]
*
* dedicato a Marika e Paola
*
*/
int x1
, y1
, a1
; /* coordinate dei vertici */
int x2
, y2
, a2
; /* e direzione della diagonale */
int x3
, y3
, a3
;
int x4
, y4
, a4
;
int dlimit
; /* limite di danni prima dello spostamento */
main
()
{
int dir
;
setup
();
dlimit
= 11;
/* raggiunge l'angolo superiore sinistro */
go2angle
(x2
, y2
);
/* ciclo operativo principale */
while(1)
if (rand(2) > 0)
cw
();
else ccw
();
}
/* rotazione sul piano in senso antiorario */
ccw
()
{
spara
(a2
);
fuga
(0, 180);
spara
(a4
);
fuga
(270, 180);
spara
(a3
);
fuga
(180, 90);
spara
(a1
);
fuga
(90, 0);
}
/* rotazione sul piano in senso orario */
cw
()
{
spara
(a2
);
fuga
(270, 0);
spara
(a1
);
fuga
(0, 90);
spara
(a3
);
fuga
(90, 180);
spara
(a4
);
fuga
(180, 270);
}
/* raggiunge con movimento rettilineo un altro angolo
e spara in direzione ortogonale allo spostamento */
fuga
(dir
, sdir
)
int dir
, sdir
;
{
drive
(dir
, 100);
if (dir
== 0) while(loc_x
() < 980) shield
(dir
, sdir
);
if (dir
== 90) while(loc_y
() < 980) shield
(dir
, sdir
);
if (dir
== 180) while(loc_x
() > 20) shield
(dir
, sdir
);
if (dir
== 270) while(loc_y
() > 20) shield
(dir
, sdir
);
drive
(0,0);
}
/* fuoco di copertura durante uno spostamento */
shield
(dir
, sdir
)
int dir
, sdir
;
{
int offs
, limit
;
limit
= 81;
offs
= -80;
while(offs
< limit
)
{
fuoco
(sdir
+ offs
);
offs
+= 20;
drive
(dir
, 100);
}
}
/* raggiunge l'angolo */
go2angle
(x
, y
)
int x
,y
;
{
int dir
;
dir
= plot_course
(x
, y
);
while (loc_x
() > 25 || loc_y
() < 975)
{
fuoco
(dir
); /* scaccia eventuali intrusi */
fuoco
(0); /* protezione limitata, */
fuoco
(90); /* ma talvolta utile */
fuoco
(180);
fuoco
(270);
drive
(dir
, 100);
}
drive
(0,0);
}
/* spara nel quadrante; se subisce danni esce
e si attiva la routine di spostamento */
spara
(dir
)
int dir
;
{
int danni
, offs
, limit
;
danni
= damage
() + dlimit
;
limit
= 41;
while(danni
> damage
() )
{
offs
= -40;
while((offs
< limit
) && (danni
> damage
()))
{
fuoco
(dir
+ offs
);
offs
+= 20;
}
} /* si sposta per cercare di limitare i danni */
}
/* inizializza le varibili di riferimento */
setup
()
{
x1
= 20; y1
= 20; a1
= 45;
x2
= 20; y2
= 980; a2
= 315;
x3
= 980; y3
= 20; a3
= 135;
x4
= 980; y4
= 980; a4
= 225;
}
/* controlla bersaglio e spara */
fuoco
(a
)
int a
;
{
int range
, offs
, dir
, danni
;
danni
= damage
() + dlimit
;
if (range
= scan
(a
, 10))
{
offs
= -9;
cannon
(a
, range
); /* spara un colpo sperando nella fortuna */
/* ricerca la posizione precisa */
while ((offs
< 10) && (danni
> damage
()))
{
dir
= (a
+ offs
) % 360;
range
= scan
(dir
, 2);
if ((range
> 0) && (range
< 700))
{
cannon
(dir
, range
);
offs
= -9; /* ripete lo scaning locale */
}
else offs
+= 3;
} /* fine loop while */
}
}
/* plot course function, return degree heading to */
/* reach destination x, y; uses atan() trig function */
/* tratta da sniper.r */
plot_course
(xx
,yy
)
int xx
, yy
;
{
int d
;
int x
,y
;
int scale
;
int curx
, cury
;
scale
= 100000; /* scale for trig functions */
curx
= loc_x
(); /* get current location */
cury
= loc_y
();
x
= curx
- xx
;
y
= cury
- yy
;
/* atan only returns -90 to +90, so figure out how to use */
/* the atan() value */
if (x
== 0) { /* x is zero, we either move due north or south */
if (yy
> cury
)
d
= 90; /* north */
else
d
= 270; /* south */
} else {
if (yy
< cury
) {
if (xx
> curx
)
d
= 360 + atan((scale
* y
) / x
); /* south-east, quadrant 4 */
else
d
= 180 + atan((scale
* y
) / x
); /* south-west, quadrant 3 */
} else {
if (xx
> curx
)
d
= atan((scale
* y
) / x
); /* north-east, quadrant 1 */
else
d
= 180 + atan((scale
* y
) / x
); /* north-west, quadrant 2 */
}
}
return (d
);
}