Programmeerimise algkursus Harjutus 5
Meie robotile on nüüd küll raskem pihta saada, aga sõitmine segab tugevalt laskmist. Tegelikult on täiesti võimalik teha mitut asja korraga ning see polegi teab mis keeruline.
Arenenud Robot
Mitut asja korraga saab teha vaid siis, kui tegemist on nn. "arenenud" robotiga (Advanced Robot). Meil ei jää muud üle, kui oma robot ahvist inimeseks arendada.
public class LollRobot extends AdvancedRobot {
String siga_sihikul; // Siga, mida me seekord sihime
String uus_siga; // Vahemuutujad uue lähima vastase leidmiseks
double min_kaugus;
...
Muutub kaks asja:
- Tekib võimalus kasutada mitteblokeeruvaid käske kujul setTeeMidagi (näiteks setTurnRight).
- Robot hakkab vastu seinu sõites haiget saama
Tekitame igiliikuva radari
Et liikumine ei segaks laskmist, tuleb siduda radari keeramine ja liikumine üksteisest lahku. Selleks kolime radari keeramise koodi eraldi meetodisse ja asendame turnRadarLeft käsu setTurnRadarLeft käsuga.
public void onRadarTurnComplete() { // Enne otsimist on lähim siga lõpmata kaugel min_kaugus = Double.POSITIVE_INFINITY; // Hakka taustal uuesti radarit keerama setTurnRadarLeft(360); // Kuningas on surnud, elagu kuningas siga_sihikul = uus_siga; }
Järgmiseks organiseerime, et meie kirjutatud uus meetod käivitataks iga kord, kui radari ring saab täis. Selleks tuleb registreerida uus sündmus (customEvent). Seda tuleb teha run meetodis, vahetult enne while tsüklit.
NB! Pane tähele, et run meetodist on juba kogu radari kood ära koristatud!
public void run() {
// Ära keera tukki koos kerega ega radarit koos tukiga!
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
// Registreerime uue sündmuse, mis käivitub, kui radaritiir on tehtud
addCustomEvent(new RadarTurnCompleteCondition(this));
// Käivitame esimese radaritiiru
onRadarTurnComplete();
while(true) {
// Dingel-dangel, kellapendel
ahead(100 * suund);
suund = -suund;
}
}
Lisaks peame tegema veel ühe uue meetodi:
public void onCustomEvent(CustomEvent e) { String s = e.getCondition().getName(); if("robocode.RadarTurnCompleteCondition".equals(s)) { onRadarTurnComplete(); } }
Ja ongi kõik!
Robot on nüüd palju krapsakam, kas pole?
Saab veel krapsakamaks, kui asendada õiges kohas turnLeft käsk setTurnLeft käsuga ;)
Iseseisev töö
Arenenud robot saab vastu seinu sõites haiget. Seetõttu tuleb enne liikuma hakkamist kontrollida, kas mitte sein ette ei jää. Täienda run meetodis asuvat edasi-tagasi sõitmise koodi nii, et kontrollitakse, kas sein on lähemal kui 150 pikslit ja kui on, siis sätitakse suund selliselt, et robot sõidab seinast eemale, mitte seina poole. Abiks on järgmised meetodid:
- getX() - minu X koordinaat
- getY() - minu Y koordinaat
- getBattleFieldWidth() - Mänguvälja laius
- getBattleFieldHeight() - Mänguvälja kõrgus
- getHeading() - Suund kraadides, kuhu poole on minu nina (mäletate, 0 kraadi oli otse üleval).
Lisalugemist
Igasugused kavalad liikumisalgoritmid kasutavadki enamasti arenenud robotit. Mõned lihtsamad leiad siit: