Ultimo aggiornamento: 18-nov-1999
Questa pagina è semplicemente una collezione
delle esperienze fatte da alcuni croboticisti alle prese con il bug dell'
angolo 0.
Iniziamo con Daniele Nuzzo:
Ho fatto qualche prova per vedere quanto possa influire il bug sui risultati.
Con questi due semplicissimi crobots...
/* Fix.r: fa da bersaglio */
main()
{
while (loc_x()<850) drive(0,45);
drive (0,0);
while (loc_y()>100) drive(270,45);
drive (270,0);
while (loc_y()<100) drive(90,10);
drive (90,0);
while(speed()) ;
while (1) if (loc_y()==100) cannon(90,400);
}
/* Fix2.r: verifica il bug */
int t,rng;
main()
{
while (loc_x()>500) drive(180,45);
drive (180,0);
while (loc_x()<500) drive(0,45);
drive (0,0);
while (loc_y()>100) drive(270,45);
drive (270,0);
while (loc_y()<100) drive(90,10);
drive (90,0);
t=500;
while(speed()) ;
while (--t) if (loc_y()==100) cannon(90,400);
while (1) if (rng=scan(0,10)) cannon(0,rng);
}
... si puo' verificare con assoluta certezza se c'e' il bug: infatti
si
posizionano sulla stessa ordinata (y=100) a distanza di circa 500
e, dopo
aver verificato, sparando in aria mentre sono fermi, che il valore
di y sia
corretto per entrambi Fix2.r fa fuori Fix.r (ma solo se lo vede!!!).
Modificando leggermente i due crobots si possono effettuare diverse
prove
per vedere quali sono gli angoli in cui c'e' il bug (se ne fate
qualcuno
date i risultati, cosi' cerchiamo di capirci qualcosa in piu').
Io ho modificato fix2 in questo modo:
int t,rng;
main()
{
while (loc_x()>500) drive(180,45);
drive (180,0);
while (loc_x()<500) drive(0,45);
drive (0,0);
while (loc_y()>100) drive(270,45);
drive (270,0);
while (loc_y()<100) drive(90,10);
drive (90,0);
t=500;
while(speed()) ;
while (--t) if (loc_y()==100) cannon(90,400);
while (1) {
if (rng=scan(349,10)) cannon(0,rng);
if (rng=scan(371,10)) cannon(0,rng);
if (rng=scan(360,0)) cannon(0,rng);
if (rng=scan(0,0)) cannon(0,rng);
if (rng=scan(0,3)) cannon(0,rng);
if (rng=scan(360,3)) cannon(0,rng);
if (rng=scan(0,10)) cannon(0,rng);
if (rng=scan(5,5)) cannon(0,rng);
if (rng=scan(-5,5)) cannon(0,rng);
if (rng=scan(-1,0)) cannon(0,rng);
if (rng=scan(1,0)) cannon(0,rng);
if (rng=scan(-2,0)) cannon(0,rng);
if (rng=scan(2,0)) cannon(0,rng);
if (rng=scan(-3,0)) cannon(0,rng);
if (rng=scan(3,0)) cannon(0,rng);
if (rng=scan(361,0)) cannon(0,rng);
if (rng=scan(362,0)) cannon(0,rng);
if (rng=scan(363,0)) cannon(0,rng);
if (rng=scan(359,0)) cannon(0,rng);
if (rng=scan(358,0)) cannon(0,rng);
if (rng=scan(357,0)) cannon(0,rng);
if (rng=scan(0,1)) cannon(0,rng);
if (rng=scan(1,1)) cannon(0,rng);
if (rng=scan(2,1)) cannon(0,rng);
if (rng=scan(-1,1)) cannon(0,rng);
if (rng=scan(-2,1)) cannon(0,rng);
}
}
... e facendo combattere 2000 incontri con limite 40000 (piu' che
sufficiente) ho ottenuto i seguenti risultati:
Nome del Robot Partite Partite
Partite Partite Punteggio Perc
Combattente Giocate
vinte Nulle Perse
Ottenuto %
1 fix2
2000 1390 610
0 4780
79.6
2 fix
2000 0
610 1390
610 10.1
Scheda tecnica del Crobot fix2
Partite combattute 2000
Punteggio finale 4780
Partite vinte 1390
Efficienza 79.6
Partite pareggiate 610
Partite perse 0
Le vittorie sono maturate cosi'
CPU * 10000 |<2 |<4
|<6 |<8 |<10 |<12 |<14 |<16 |<18 |<20
|Pari
| | | |
| | | |
| | |
0 <Danni< 20 |1387|3
|0 |0 |0 |0 |0
|0 |0 |0 |610
20 <Danni< 40 |0 |0
|0 |0 |0 |0 |0
|0 |0 |0 |0
40 <Danni< 60 |0 |0
|0 |0 |0 |0 |0
|0 |0 |0 |0
60 <Danni< 80 |0 |0
|0 |0 |0 |0 |0
|0 |0 |0 |0
80 <Danni< 100 |0 |0
|0 |0 |0 |0 |0
|0 |0 |0 |0
fix2 ha riportato i seguenti risultati
Nome del Robot Partite Partite
Perc. Partite Percentuale
Combattente giocate
vinte vitt. patte
aggiustata
1 fix 2000 1390 69.5 610 79.6
Considerazioni:
1) in almeno il 30% dei casi il bersaglio sparisce e non c'e' modo
di
trovarlo!!!
2) sembra che il bug ci sia nell'intervallo da -10 a zero.
Ma Maurizio Camangi non sembra essere daccordo:
Ragazzi! Spero di aver ragione!
Ho ripreso in mano i due robottini di prova di Daniele, fix.r e
fix2.r (vi
ricordate i risultati ottenuti?).
Ho modificato fix2.r usando tutti angoli positivi, sommando 360
ove necessario, ed ecco il listato:
(commentato il codice originale di Daniele)
/* Fix2.r: verifica il bug */
int t,rng;
main()
{
while (loc_x()>500) drive(180,45);
drive (180,0);
while (loc_x()<500) drive(0,45);
drive (0,0);
while (loc_y()>100) drive(270,45);
drive (270,0);
while (loc_y()<100) drive(90,10);
drive (90,0);
t=500;
while(speed()) ;
while (--t) if (loc_y()==100) cannon(90,400);
while (1) {
/* codice originale
if (rng=scan(349,10)) cannon(0,rng);
if (rng=scan(371,10)) cannon(0,rng);
if (rng=scan(360,0)) cannon(0,rng);
if (rng=scan(0,0)) cannon(0,rng);
if (rng=scan(0,3)) cannon(0,rng);
if (rng=scan(360,3)) cannon(0,rng);
if (rng=scan(0,10)) cannon(0,rng);
if (rng=scan(5,5)) cannon(0,rng);
if (rng=scan(-5,5)) cannon(0,rng);
if (rng=scan(-1,0)) cannon(0,rng);
if (rng=scan(1,0)) cannon(0,rng);
if (rng=scan(-2,0)) cannon(0,rng);
if (rng=scan(2,0)) cannon(0,rng);
if (rng=scan(-3,0)) cannon(0,rng);
if (rng=scan(3,0)) cannon(0,rng);
if (rng=scan(361,0)) cannon(0,rng);
if (rng=scan(362,0)) cannon(0,rng);
if (rng=scan(363,0)) cannon(0,rng);
if (rng=scan(359,0)) cannon(0,rng);
if (rng=scan(358,0)) cannon(0,rng);
if (rng=scan(357,0)) cannon(0,rng);
if (rng=scan(0,1)) cannon(0,rng);
if (rng=scan(1,1)) cannon(0,rng);
if (rng=scan(2,1)) cannon(0,rng);
if (rng=scan(-1,1)) cannon(0,rng);
if (rng=scan(-2,1)) cannon(0,rng);
*/
if (rng=scan(349,10)) cannon(360,rng);
if (rng=scan(371,10)) cannon(360,rng);
if (rng=scan(360,0)) cannon(360,rng);
if (rng=scan(360,0)) cannon(360,rng);
if (rng=scan(360,3)) cannon(360,rng);
if (rng=scan(360,3)) cannon(360,rng);
if (rng=scan(360,10)) cannon(360,rng);
if (rng=scan(365,5)) cannon(360,rng);
if (rng=scan(355,5)) cannon(360,rng);
if (rng=scan(359,0)) cannon(360,rng);
if (rng=scan(361,0)) cannon(360,rng);
if (rng=scan(358,0)) cannon(360,rng);
if (rng=scan(362,0)) cannon(360,rng);
if (rng=scan(357,0)) cannon(360,rng);
if (rng=scan(363,0)) cannon(360,rng);
if (rng=scan(361,0)) cannon(360,rng);
if (rng=scan(362,0)) cannon(360,rng);
if (rng=scan(363,0)) cannon(360,rng);
if (rng=scan(359,0)) cannon(360,rng);
if (rng=scan(358,0)) cannon(360,rng);
if (rng=scan(357,0)) cannon(360,rng);
if (rng=scan(360,1)) cannon(360,rng);
if (rng=scan(361,1)) cannon(360,rng);
if (rng=scan(362,1)) cannon(360,rng);
if (rng=scan(359,1)) cannon(360,rng);
if (rng=scan(358,1)) cannon(360,rng);
}
}
Ed ecco i risultati:
Nome robot - Partite - Partite -
Partite - Partite - Punteggio - Perc
Combattente giocate
vinte patte perse
ottenuto %
1 fix2
2000 2000
0 0
6000 100.00
2 fix
2000 0
0 2000
0 0.00
Scheda tecnica del crobot fix2:
In classifica e' alla posizione numero 1
Partite combattute:2000 Punteggio finale: 6000
Partite vinte :2000 Efficienza
:100.00
Partite pareggiate: 0
Partite perse : 0
Le vittorie sono maturate cosi'
|Pareggi|
CPU * 10000 |< 2 |< 4 |< 6 |< 8 |<10 |<12
|<14 |<16 |<18 |<20 |1Sup|2Sup|3Sup
| | | |
| | | |
| | | |
|
0<Danni< 20 |1998| 2| 0|
0| 0| 0| 0| 0|
0| 0| 0| 0| 0
20<Danni< 40 | 0| 0|
0| 0| 0| 0| 0|
0| 0| 0| 0| 0|
0
40<Danni< 60 | 0| 0|
0| 0| 0| 0| 0|
0| 0| 0| 0| 0|
0
60<Danni< 80 | 0| 0|
0| 0| 0| 0| 0|
0| 0| 0| 0| 0|
0
80<Danni<100 | 0| 0|
0| 0| 0| 0| 0|
0| 0| 0| 0| 0|
0
fix2 ha riportato i seguenti risultati
Nome del Robot Partite Partite
Perc. Partite Percentuale
Combattente giocate
vinte vitt. patte
aggiustata
1 fix
2000 2000 100.00
0 100.00
Che cosa vi avevo detto io???!!!???
Crobots effettua l'operazione di modulo per angoli negativi; nel
codice di
Daniele alcuni scan(), usano numeri negativi o nulli (o cmq valori
per cui il range +/- 10 gradi finisce nei negativi); sostituendo a tali
valori quelli che si ottengono sommando 360 funziona tutto.
Ditemi che non ho bevuto :-)
Purtroppo per noi però ha ragione Daniele:
No, Maurizio; purtroppo il bug c'e'!!! Anche se sotto Linux la situazione
è migliore!!!
Ho provato lo stesso codice sotto Linux ed in effetti i risultati
sono gli
stessi dei tuoi, ma nel while ci sono numerosi scan in cascata,
che combinati annullano l'effetto del bug. Anche se in realta' bastano
2 scan
per verificare la presenza dei robot in direzione zero (circa);
con uno
solamente non funziona, mentre dovrebbe!!! Se provi inserendo scan(360,10)
da solo non basta ad eliminare il bug, che quindi c'e' sicuramente.
Si puo' invece risolvere il problema con 2 scan tipo scan(355,5)+scan(365,5)
oppure scan(350,10)+scan(370,10).
Dopo aver fatto ulteriori prove, penso che in questo caso (con
Linux) il bug abbia questo effetto: divide in due parti l'angolo di scansione
in
corrispondenza dello zero (o multipli modulo 360); quindi se la
scansione
parte da un angolo che si trova sopra lo zero individuera' tutti
i crobots
sopra, ma non quelli sotto lo zero; viceversa, se l'angolo iniziale
di
scansione e' inferiore a zero. Lo zero dovrebbe essere incluso
nella
scansione positiva, ma non in quella negativa e cio' introduce
un ulteriore problema: e' piu' probabile che un robot in movimento riesca a
"passare"
indenne anche ai 2 scan combinati (ecco spiegato perche' in genere
si
controlla l'arena con incrementi di 20 gradi e non di 21).
Concludendo credo che comunque la situazione sia molto piu' gestibile
almeno per il controllo dell'arena prima degli spostamenti. Rimane il problema
per le routine di fuoco che con ulteriori controlli rischiano di diventare
troppo lente.