/* V I S I O N AUTORE Nome: Alessandro Carlin SCHEDA TECNICA: Inizialmente il crobot si porta vicino alla cima dello schermo, e da questa posizione controlla l' angolo NORD-EST; nel caso in cui sia libero lo raggiunge, altrimenti va ad occupare l' angolo NORD-OVEST. Raggiunta una di queste posizioni inizia un movimento oscillatorio di circa 200 metri che avviene in direzione verticale se non ci sono nemici negli angoli adiacenti, e diventa orizzontale se e' presente un crobot nell' angolo inferiore. Durante questa fase (che dura almeno 8E+4 cicli virtuali di CPU) Vision utilizza 2 diverse procedure di fuoco: kill() che consente un puntamento molto preciso ma e' piuttosto lenta, e mortal() che e' di esecuzione molto piu' rapida. Successivamente il crobot inizia ad effettuare dei controlli (circa ogni 15 oscillazioni) sui robot rimasti: se ne individua uno solo e i danni sono minori dell' 80% lo attacca con la procedura attack() portandosi al centro del campo ed oscillando in direzione orizzontale. La funzione di sparo e' diversa dalle due precedenti ed e' divisa in due parti distinte: destroy() e shot(). PRECISAZIONI: 1) La routine di puntamento piu' precisa deriva dal crobot JEDI che ha partecipato alla scorsa edizione del torneo. 2) La procedura di attacco e' molto simile a quella del crobot ARALE ma e' stata migliorata apportando una semplice correzione sulla gittata ed un puntamento piu' preciso nella sottoroutine di sparo rapido. 3) Il movimento oscillatorio o la vicinanza di due nemici fa si che talvolta la funzione di controllo sul numero di nemici (radar()) sbagli; di conseguenza Vision puo' attaccare anche se sono presenti 2 (molto raramente 3) nemici. Non so se in effetti questo sia un inconveniente o no: infatti quando Vision attacca e' nella zona centrale e puo' essere colpito da chiunque, mentre lui attacca un nemico alla volta. Quindi la procedura funziona al meglio contro un solo avversario; tuttavia si e' dimostrata cosi' efficiente che spesso riesce a sconfiggere due nemici senza riportare troppi danni. 4) Quest' anno ho spedito due crobot (gemelli), ma quello che preferisco veder combattere nel caso fosse necessario limitare la partecipazione ad un solo concorrente e' The Invisible Man. COMMENTO: L' uso di due procedure di fuoco mentre oscilla dipende dal fatto che mortal(),pur essendo meno precisa, e' molto piu' veloce; questo permette al crobot di avvicinarsi con piu' precisione ai muri senza spalmarsi; inoltre negli scontri ravvicinati mortal() non e' molto inferiore a kill(). Il cambiamento di direzione nell' oscillazione e la scelta iniziale dell' angolo sono ovviamente accorgimenti volti a mantenere Vision fuori tiro per gli altri crobots. Infine mi pare molto intelligente fare attaccare il crobot solo quando e' rimasto un avversario solo nell' arena anziche' rischiare di fare i kamikaze contro 3 avversari; soprattutto e' importante attaccare APPENA rimane solo un nemico per evitare di attendere troppo e di essere attaccati. Mi sembra a proposito giusto far notare che la funzione radar() (peraltro semplicissima) era gia' stata usata da TEQUILA 3 anni fa. NOTE: Ho avuto non poche difficolta' ad ottimizzare il codice, e ho dovuto rinunciare ad alcuni miglioramenti che volevo apportare (ad esempio la possibilita' di svariare su 4 angoli) per l' ormai famigerata limitazione sulla lunghezza del listato. Penso quindi che senza riprogrammare il compilatore da zero basterebbe alzare questa soglia per aumentare notevolmente la competitivita' dei robot e, di conseguenza, la longevita' del gioco (gia' elevatissima). */ /* ONE VISION... */ int pp,dz,dw,dx,su,via,ang,dir,cont,c; /* ONE MAN ONE GOAL ONE MISSION... */ main() { c=14; ang=0; cont=0; drive(dir=90,100); while (loc_y() < 840) kill(); stop(); if ((!scan(0,10))&&(!scan(342,10))) { drive(dir=0,100); dz=180; dw=0; dx=1; while(loc_x() < 860) { kill(); } stop(); } else { drive(dir=180,100); dz=0; dw=180; dx=0; while(loc_x() > 160) { kill(); } stop(); } while(1) { su=scan(270,10); via=scan(dz,10); if (su<=via){ drive(dir=270,100); while (loc_y() > 685) { kill(); } stop(); drive(dir=90,100); kill(); kill(); while (loc_y() < 910) { mortal(); } stop(); } else { drive(dir=dz,100); if (dx==0) while(loc_x() <= 285) { kill(); } else while(loc_x() >715) { kill(); } stop(); drive(dir=dw,100); kill(); kill(); if (dx==0) while(loc_x() > 95) { mortal(); } else while(loc_x() < 910) { mortal(); } stop(); } } } int d,oang,range,orange,aa,rr,diff; /* ...ONE HEART ONE SOUL JUST ONE SOLUTION... */ search() { if(scan(ang-5,1)) ang-=5; if(scan(ang+5,1)) ang+=5; if(scan(ang-3,1)) ang-=3; if(scan(ang+3,1)) ang+=3; if(scan(ang-1,1)) ang-=1; if(scan(ang+1,1)) ang+=1; } /* ...ONE FLASH OF LIGHT ONE GOAL ONE VISION... */ kill() { if(range=scan(ang,5)) { cannon(ang,range); search(); if (range=scan(ang,5)) { orange=range; oang=ang; search(); if (range=scan(ang,10)) { aa=(ang+(ang-oang)*((1200+range)>>9)-(sin(ang-dir)>>14)); rr=(range*160/(160+orange-range-(cos(ang-dir)>>12))); while(!cannon(aa,rr)); if (range>700) ang+=30; } else if(scan(ang-=10,10)); else if(scan(ang+=20,10)); else ang+=40; } else if(scan(ang-=10,10)); else if(scan(ang+=20,10)); else ang+=40; } else if(scan(ang-=10,10)); else if(scan(ang+=20,10)); else ang+=40; } /* ...ONE FLASH ONE BONE ONE TRUE RELIGION... */ attack() { while(loc_y()>550) {drive(270,100);destroy();} drive(270,0); while(speed()>49) destroy(); while(1) { drive(0,100); while (loc_x() < 900) destroy(); drive(0,0); shot(); drive(180,100); while (loc_x() > 100) destroy(); drive(180,0); shot(); } } /* ...ONE VOICE ONE HOPE ONE REAL DECISION... */ destroy(){ if (pp=scan(ang,10)) cannon(ang+=7*(!(scan(ang+356,7)))+353*(!(scan(ang+4,7))),2*scan(ang,10)-pp); else ang+=21; } /* NO WRONG NO RIGHT I 'M GONNA TELL YOU THERE 'S NO BLACK AND NO WHITE... */ stop() { drive(dir,0); if ((++cont >= 86) && (damage() < 80)) {++c; if (c%15==0) {if(radar()<2) attack();} } while(speed() > 49) mortal(); } /* ...NO BLOOD NO STAIN ALL WE NEED IS ONE WORLD WIDE VISION... */ mortal() { if ( (d=scan(ang,10)) && (d<750) ) { if (d=scan(ang+353,3)) cannon(ang+=353,d); else if (d=scan(ang,3)) cannon(ang,d); else if (d=scan(ang+7,3)) cannon(ang+=7,d); } else { if ((d=scan(ang+21,10))&&(d<710)) {ang+=21;cannon(ang,d);} else if ((d=scan(ang+42,10))&&(d<710)) ang+=42; else ang+=63; } } /* I HAD A DREAM WHEN I WAS YOUNG A DREAM OF SWEET ILLUSION A GLIMPSE OF HOPE AND UNITY AND VISIONS OF ONE SWEET UNION... */ radar() { int num,da; num=0; da=1; while (da!=361) { if (scan(da,10)) ++num; da+=18; } return num; } /* ...BUT A WILD WIND BLOWS AND A DARK RAIN FALLS... */ shot() { while (speed() > 49) if ((d=scan(ang,10))) { if (!scan(ang+=5,5)) ang-=10; cannon(ang,d); } else ang+=20; } /* ...LOOK WHAT I 'VE DONE TO MY DREAM... */