Programmeerimise algkursus Harjutus 3: erinevus redaktsioonide vahel

Allikas: Lambda
Mine navigeerimisribale Mine otsikasti
Anttix (arutelu | kaastöö)
Anttix (arutelu | kaastöö)
Resümee puudub
1. rida: 1. rida:
Meie eelmises tunnis ehitatud vastaseid sihtiv robot on väga tore, aga kahe või enama roboti puhul võib
kergesti jääda nagu kits kahe heinakuhja vahel valides toru edasi-tagasi väntsutama ja korralikult
laskmiseni ei jõuagi. Samuti jätab kiiresti liikuvate vastaste puhul tabamistäpsus kõvasti soovida.
Vaja oleks seltsimees veidi targemaks teha.
== Esimene töö: valida sihtimiseks siga, mis on meile kõige lähemal. ==
== Esimene töö: valida sihtimiseks siga, mis on meile kõige lähemal. ==


Idee: teeme radariga tiiru ära ja märgime tiiru jooksul leitud sigadest kõige lähemal olnu kauguse ja peilungi ära. Peale tiiru lõpetamist keerame tuki sea suunas ja anname tina!
Idee: teeme radariga tiiru ära ja jätame tiiru jooksul leitud sigadest kõige lähemal olnud sea meelde.
Järgmise radaritiiru ajal keerame tuki valitud sea suunas ja anname tina, otsides samal ajal uut "lähimat".


Algatuseks peame onScannedRobot sündmusest üleliigse kõntsa ära koristama. Seal istub praegu keeramisnurga arvutamise kood, millest teeme eraldi funktsiooni (meil läheb seda hiljem niikuinii vaja):
Algatuseks peame onScannedRobot sündmusest üleliigse kõntsa ära koristama. Seal istub praegu keeramisnurga arvutamise kood, millest teeme eraldi funktsiooni (meil läheb seda hiljem niikuinii vaja):
17. rida: 23. rida:
</pre>
</pre>


Teeme globaalmuutujad sea_kaugus ja siga_sihikul. Selleks lisame kaks uut rida oma roboti klassi algusesse:
Teeme globaalmuutujad uus_siga, min_kaugus, siga_sihikul ja laksuTugevus.
Selleks lisame neli uut rida oma roboti klassi algusesse:
<pre>
<pre>
public class LollRobot extends Robot {
public class LollRobot extends Robot {


     double siga_sihikul;
    String siga_sihikul;      // Siga, mida me seekord sihime
     double sea_kaugus;
    String uus_siga;          // Vahemuutujad uue lähima vastase leidmiseks
     double min_kaugus;
     double laksuTugevus = 2.0; // Kui kõvasti me kavatseme laskma hakata?


...
...
28. rida: 37. rida:
</pre>
</pre>


Radari keerutamisel käivitub iga sea kohta onScannedRobot sündmus. Sündmus peab märkima ära kõige lähemal olnud sea.
Radari keerutamisel käivitub iga nähtud vastase kohta onScannedRobot sündmus.
Sündmus peab tegema kahte asja:
* Märgib ära tiiru jooksul kõige lähemal olnud sea.
* kui näeb eelmise tiiru ajal märgitud siga, siis annab tina!


Lähima vastase leidmise algoritm töötab järgmiselt:
* Iga radaritiiru alguses seatakse min_kaugus võrdseks lõpmatusega.
* Kontrollitakse, kas vastane on lähemal kui kõik teised sama tiiru jooksul leitud vastased (min_kaugus)
* Kui jah, seatakse min_kaugus võrdseks leitud vastase kaugusega ja uus_siga võrdseks vastase nimega.
onScannedRobot meetod:
<pre>
<pre>
     public void onScannedRobot(ScannedRobotEvent e) {
     public void onScannedRobot(ScannedRobotEvent e) {
         double vastase_kaugus = e.getDistance();
         double vastase_kaugus = e.getDistance();
         double vastase_peilung = e.getBearing();
         double vastase_peilung = e.getBearing();
        String vastase_nimi = e.getName();


         // Otsime kõige lähemal paiknevat vastast
         // Kas on meie väljavalitu?
         if(vastase_kaugus < sea_kaugus) {
        if(vastase_nimi.equals(siga_sihikul)) {
             sea_kaugus = vastase_kaugus;
            // Keerame tuki sea suunda ja anname tina!
             siga_sihikul = vastase_peilung;
            double keeramisnurk = arvutaKeeramisnurk(vastase_peilung);
            turnGunRight(keeramisnurk);
            fire(laksuTugevus);
        }
        // Kas on lähemal, kui kõik teised?
         if(vastase_kaugus < min_kaugus) {
             uus_siga = vastase_nimi;
             min_kaugus = vastase_kaugus;
         }
         }
     }
     }
</pre>
</pre>


Tuki keeramine ja laskmine hakkavad toimuma peale radari "scan"-i. Modifitseerime run meetodit vastavalt:
Run meetod:
 
<pre>  
<pre>  
    double laksuTugevus = 2.0;
     public void run() {
     public void run() {
         // Ära keera tukki koos kerega ega radarit koos tukiga!
         // Ära keera tukki koos kerega ega radarit koos tukiga!
55. rida: 79. rida:
         while(true) {
         while(true) {
             // Enne otsimist on lähim siga lõpmata kaugel
             // Enne otsimist on lähim siga lõpmata kaugel
             sea_kaugus = Double.MAX_VALUE;
             sea_kaugus = Double.POSITIVE_INFINITY;


             // Radari scan
             // Radari scan
             turnRadarLeft(360);
             turnRadarLeft(360);


             // Keerame tuki sea suunda ja anname tina!
             // Kuningas on surnud, elagu kuningas
             double keeramisnurk = arvutaKeeramisnurk(siga_sihikul);
             siga_sihikul = uus_siga;
            turnGunRight(keeramisnurk);
            fire(laksuTugevus);
         }
         }
     }
     }
70. rida: 92. rida:
== Teine töö: arvutada sea sibamiskiiruse järgi ettelaskmisnurk ==
== Teine töö: arvutada sea sibamiskiiruse järgi ettelaskmisnurk ==


Meie praegune robot laseb sinna, kus ta siga nägi. Inglise keeles nimetatakse seda Head-On targeting.
Meie praegune robot laseb sinna, kus ta vastast nägi. Inglise keeles nimetatakse seda Head-On targeting.


Kuna kuuli lendamine võtab oma aja, siis liikuvat siga pole alati mõtet sihtida sinna, kus ta parasjagu on,
Kuna kuuli lendamine võtab oma aja, siis liikuvat vastast pole alati mõtet sihtida sinna, kus ta parasjagu on,
vaid natuke temast ette poole. Põhimõtteliselt saame liikumiskiiruse (loe: kohvipaksu) pealt "ennustades" arvutada, kus vastane kuuli kohalejõudmise ajaks tegelikult olla võiks ja suunata oma toru sinna.
vaid natuke temast ette poole. Põhimõtteliselt saame liikumiskiiruse (loe: kohvipaksu) pealt "ennustades" arvutada, kus vastane kuuli kohalejõudmise ajaks tegelikult olla võiks ja suunata oma toru sinna.


90. rida: 112. rida:


Natuke trigonomeetriat meelde tuletades avastame, et ettelaskmisnurga saab arvutada:
Natuke trigonomeetriat meelde tuletades avastame, et ettelaskmisnurga saab arvutada:
 
ettelaskmisnurk = asin(vastase kiirus / kuuli kiirus)
<pre>
ettelaskmisnurk = asin(vastase kiirus / kuuli kiirus)
</pre>


Kuuli lennuaeg taandub mõnusasti valemist välja. Järelikult on nurga arvutamiseks vaja teada ainult vastase kiirust ja kuuli lennukiirust.
Kuuli lennuaeg taandub mõnusasti valemist välja. Järelikult on nurga arvutamiseks vaja teada ainult vastase kiirust ja kuuli lennukiirust.


Robocode "füüsikareeglid"[http://testwiki.roborumble.org/w/index.php?title=Robocode/Game_Physics] annavad kuuli lennukiiruse arvutamiseks järgmise valemi:
Robocode [http://testwiki.roborumble.org/w/index.php?title=Robocode/Game_Physics "füüsikareeglid"] annavad kuuli lennukiiruse arvutamiseks järgmise valemi:
 
kuuli kiirus = 20 - 3 * laksu tugevus
<pre>
kuuli kiirus = 20 - 3 * laksu tugevus
</pre>


Vastase kursi ja liikumiskiiruse saab küsida funktsioonidega e.getHeading() ja e.getVelocity().
Vastase liikumiskiiruse saab küsida funktsiooniga e.getVelocity().


Paraku ei ole asi päris nii lihtne: meil on vaja teada vastase kiiruse seda komponenti, mis sunnib meid tema sihtimiseks toru keerama, teisisõnu: meid ei huvita kui kiiresti ta meie poole või meist eemale sõidab. Nö "vasakule-paremale" kiirust meie suhtes nimetatakse peenelt lateraalkiiruseks [http://robowiki.net/cgi-bin/robowiki?LateralVelocity].
Paraku ei ole asi päris nii lihtne: meil on vaja teada vastase kiiruse seda komponenti, mis sunnib meid tema sihtimiseks toru keerama, teisisõnu: meid ei huvita kui kiiresti ta meie poole või meist eemale sõidab. Nö "vasakule-paremale" kiirust meie suhtes nimetatakse peenelt [http://robowiki.net/cgi-bin/robowiki?LateralVelocity lateraalkiiruseks].  


Lateraalkiiruse siht on alati täpselt risti vastase peilungiga. Oletame, et vastane liikus punktis s punkti s'.
Lateraalkiiruse siht on alati täpselt risti vastase peilungiga. Oletame, et vastane liikus punktist s punkti s'.
Lateraalkiiruse saamiseks tuleb korrutada kiirus (vektori pikkus) kiirusvektori ja peilungi vahelise nurga siinusega.
Lateraalkiiruse saamiseks tuleb korrutada kiirus (vektori pikkus) kiirusvektori ja peilungi vahelise nurga siinusega.
<pre>                 
<pre>                 
120. rida: 136. rida:
</pre>
</pre>


Kiirusvektori ja peilungi vahelise nurga saamiseks lahutame vastase kursist (liikumise suunast) maha vastase suuna (peilung absoluutkoordinaadistikus, ehk minu suund + peilung minu suuna suhtes).
Vastase kiirusvektori suuna ehk kursi saame e.getHeading() funktsiooni abil.
Kiirusvektori ja peilungi vahelise nurga saamiseks lahutame vastase kursist maha vastase suuna. Viimane on nurk absoluutkoordinaadistikus (null kraadi on mänguväljal otse üleval) ja peaks olema meile juba tuttav suurus.


  vastase suund = peilung + minu suund
  vastase suund = peilung + minu suund
  lateraalkiirus = kiirus * sin(vastase kurss - vastase suund)
  lateraalkiirus = kiirus * sin(vastase kurss - vastase suund)


Nüüd on meil olemas kõik vajalik, et kirjutada funktsioon ettelaskmisnurga arvutamisks. Kuna aga java.Math pakis leiduvad trigonomeetrilised funktsioonid kasutavad radiaane, tuleb kraadid enne arvutamist radiaanideks konverteerida ja pärast vastupidi tagasi. Abiks on funktsioonid Math.toDegrees(nurk) ja Math.toRadians(nurk).
Nüüd on meil olemas kõik vajalik, et kirjutada funktsioon ettelaskmisnurga arvutamisks. Kuna aga java.Math pakis leiduvad trigonomeetrilised funktsioonid kasutavad radiaane mitte kraade, tuleb kraadid enne arvutamist radiaanideks konverteerida ja pärast vastupidi tagasi. Abiks on funktsioonid Math.toDegrees(nurk) ja Math.toRadians(nurk).


<pre>
<pre>
142. rida: 159. rida:
     }
     }
</pre>
</pre>
Jääb veel üle integreerida ettelaskmisnurga arvutamine robotisse.
Jääb veel üle integreerida ettelaskmisnurga arvutamine robotisse (uued read on rohelised):
 
Uus globaalne muutuja: siga_ettelase
 
<div style="white-space: pre; font-family: monospace;">
public class LollRobot extends Robot {
    double siga_sihikul;
    double sea_kaugus;
    <span style="color: green;">double siga_ettelase;</span>
...
</div>
Lähima sea jaoks ettelaskmisnurga arvutamine onScannedRobot meetodis:
<div style="white-space: pre; font-family: monospace;">
<div style="white-space: pre; font-family: monospace;">
     public void onScannedRobot(ScannedRobotEvent e) {
     public void onScannedRobot(ScannedRobotEvent e) {
         double vastase_kaugus = e.getDistance();
         double vastase_kaugus = e.getDistance();
         double vastase_peilung = e.getBearing();
         double vastase_peilung = e.getBearing();
        String vastase_nimi = e.getName();
   
   
         // Otsime kõige lähemal paiknevat vastast
         // Kas on meie väljavalitu?
         if(vastase_kaugus < sea_kaugus) {
         if(vastase_nimi.equals(siga_sihikul)) {
            sea_kaugus = vastase_kaugus;
            siga_sihikul = vastase_peilung;
            <span style="color: green;">siga_ettelase = arvutaEttelaskmisnurk(e);</span>
        }
    }
</div>
Ettelaskmisnurga kasutamine tuki keeramisel run meetodis:
<div style="white-space: pre; font-family: monospace;">
    double laksuTugevus = 2.0;
    public void run() {
        // Ära keera tukki koos kerega ega radarit koos tukiga!
        setAdjustGunForRobotTurn(true);
        setAdjustRadarForGunTurn(true);
        while(true) {
            // Enne otsimist on lähim siga lõpmata kaugel
            sea_kaugus = Double.MAX_VALUE;
            // Radari scan
            turnRadarLeft(360);
             // Keerame tuki sea suunda ja anname tina!
             // Keerame tuki sea suunda ja anname tina!
             double keeramisnurk = arvutaKeeramisnurk(siga_sihikul);
             double keeramisnurk = arvutaKeeramisnurk(vastase_peilung);
             <span style="color: green;">keeramisnurk = normalRelativeAngle(keeramisnurk + siga_ettelase);</span>
             <span style="color: green; font-weight: bold;">keeramisnurk = normalRelativeAngle(keeramisnurk + arvutaEttelaskmisnurk(e));</span>
             turnGunRight(keeramisnurk);
             turnGunRight(keeramisnurk);
             fire(laksuTugevus);
             fire(laksuTugevus);
        }
        // Kas on lähemal, kui kõik teised?
        if(vastase_kaugus < min_kaugus) {
            uus_siga = vastase_nimi;
            min_kaugus = vastase_kaugus;
         }
         }
     }
     }
195. rida: 184. rida:


== Iseseisev töö ==
== Iseseisev töö ==
Saavutatud robot on ikka veel vigane. Nimelt laseb ta natuke mööda.
Vastaseid sihtides ei ole mõtet lasta kogu aeg ühesuguse tugevusega kuulidega.
Põhjuseks on fakt, et radari keeramine võtab aega ja tulistamist ei alustata enne,
Lähedal asuvale vastasele saab rohkem "haiget" teha, kui panna kirja maksimumtugevusega laks. Sinu ülesanne on lisada mingi mõistlik algoritm laksu tugevuse arvutamiseks.
kui radariga on täisring ära tehtud. Mida rohkem jäi vastase avastamise hetkest radarit keerata,
Alustuseks loe läbi http://testwiki.roborumble.org/w/index.php?title=Selecting_Fire_Power
seda ebatäpsem on lask. Selle vea parandamiseks tuleb laskmine tõsta tagasi onScannedRobot meetodisse.
abiks võib olla ka robot nimega TrackFire.
Teie ülesanne on saada sellega hakkama nii, et laskmiseks lähima roboti valimine tööle jääks.
 
Vastase valimine kauguse järgi on lahe, aga suuremas seltskonnas ragistades tuleks enne maha lasta see robot, mis otseselt Sind ennast laseb. Täienda sihtmärgi valimise algoritmi nii, et kuuliga pihta saades üritatakse vastu lasta (vähemalt mõnda aega).


== Lisalugemist ==
== Lisalugemist ==
205. rida: 195. rida:
* Eeldab, et vastane liigub sirgjooneliselt (nn lineaarne sihtimine)
* Eeldab, et vastane liigub sirgjooneliselt (nn lineaarne sihtimine)
* Ei arvesta fakti, et vastane ei saa sõita läbi seina
* Ei arvesta fakti, et vastane ei saa sõita läbi seina
* Ei arvesta tuki keeramisele kuluvat aega ja laseb seetõttu natuke mööda: Mida rohkem on vastase sihikule võtmiseks vaja tukki keerata, seda ebatäpsem on lask.


Samuti ei ole mõtet lasta kogu aeg ühesuguse tugevusega kuulidega.
Turniiril võitmiseks on vaja midagi natuke "targemat".
Turniiril võitmiseks on vaja midagi natuke "targemat".
Võiduhimulised loevad neid lehekülgi ja teevad omad järeldused:
Võiduhimulised loevad neid lehekülgi ja teevad omad järeldused:

Redaktsioon: 2. oktoober 2008, kell 02:27

Meie eelmises tunnis ehitatud vastaseid sihtiv robot on väga tore, aga kahe või enama roboti puhul võib kergesti jääda nagu kits kahe heinakuhja vahel valides toru edasi-tagasi väntsutama ja korralikult laskmiseni ei jõuagi. Samuti jätab kiiresti liikuvate vastaste puhul tabamistäpsus kõvasti soovida. Vaja oleks seltsimees veidi targemaks teha.

Esimene töö: valida sihtimiseks siga, mis on meile kõige lähemal.

Idee: teeme radariga tiiru ära ja jätame tiiru jooksul leitud sigadest kõige lähemal olnud sea meelde. Järgmise radaritiiru ajal keerame tuki valitud sea suunas ja anname tina, otsides samal ajal uut "lähimat".

Algatuseks peame onScannedRobot sündmusest üleliigse kõntsa ära koristama. Seal istub praegu keeramisnurga arvutamise kood, millest teeme eraldi funktsiooni (meil läheb seda hiljem niikuinii vaja):

    public double arvutaKeeramisnurk(double vastase_peilung) {
        double tuki_suund = getGunHeading();
        double minu_suund = getHeading();

        double vastase_suund = minu_suund + vastase_peilung;
        double keeramisnurk = vastase_suund - tuki_suund;

        return normalRelativeAngle(keeramisnurk);
    }

Teeme globaalmuutujad uus_siga, min_kaugus, siga_sihikul ja laksuTugevus. Selleks lisame neli uut rida oma roboti klassi algusesse:

public class LollRobot extends Robot {

    String siga_sihikul;       // Siga, mida me seekord sihime
    String uus_siga;           // Vahemuutujad uue lähima vastase leidmiseks
    double min_kaugus;
    double laksuTugevus = 2.0; // Kui kõvasti me kavatseme laskma hakata?

...

Radari keerutamisel käivitub iga nähtud vastase kohta onScannedRobot sündmus. Sündmus peab tegema kahte asja:

  • Märgib ära tiiru jooksul kõige lähemal olnud sea.
  • kui näeb eelmise tiiru ajal märgitud siga, siis annab tina!

Lähima vastase leidmise algoritm töötab järgmiselt:

  • Iga radaritiiru alguses seatakse min_kaugus võrdseks lõpmatusega.
  • Kontrollitakse, kas vastane on lähemal kui kõik teised sama tiiru jooksul leitud vastased (min_kaugus)
  • Kui jah, seatakse min_kaugus võrdseks leitud vastase kaugusega ja uus_siga võrdseks vastase nimega.

onScannedRobot meetod:

    public void onScannedRobot(ScannedRobotEvent e) {
        double vastase_kaugus = e.getDistance();
        double vastase_peilung = e.getBearing();
        String vastase_nimi = e.getName();

        // Kas on meie väljavalitu?
        if(vastase_nimi.equals(siga_sihikul)) {
            // Keerame tuki sea suunda ja anname tina!
            double keeramisnurk = arvutaKeeramisnurk(vastase_peilung);
            turnGunRight(keeramisnurk);
            fire(laksuTugevus);	
        }
 
        // Kas on lähemal, kui kõik teised?
        if(vastase_kaugus < min_kaugus) {
            uus_siga = vastase_nimi;
            min_kaugus = vastase_kaugus;
        }
    }

Run meetod:

 
    public void run() {
        // Ära keera tukki koos kerega ega radarit koos tukiga!
        setAdjustGunForRobotTurn(true);
        setAdjustRadarForGunTurn(true);

        while(true) {
            // Enne otsimist on lähim siga lõpmata kaugel
            sea_kaugus = Double.POSITIVE_INFINITY;

            // Radari scan
            turnRadarLeft(360);

            // Kuningas on surnud, elagu kuningas
            siga_sihikul = uus_siga;
        }
    }

Teine töö: arvutada sea sibamiskiiruse järgi ettelaskmisnurk

Meie praegune robot laseb sinna, kus ta vastast nägi. Inglise keeles nimetatakse seda Head-On targeting.

Kuna kuuli lendamine võtab oma aja, siis liikuvat vastast pole alati mõtet sihtida sinna, kus ta parasjagu on, vaid natuke temast ette poole. Põhimõtteliselt saame liikumiskiiruse (loe: kohvipaksu) pealt "ennustades" arvutada, kus vastane kuuli kohalejõudmise ajaks tegelikult olla võiks ja suunata oma toru sinna.

Joonistame kolmnurga, mille ühes tipus olen mina (R) teises tipus on vastane (s) ja kolmandas tipus vastase asukoht kuuli kohalejõudmise ajal (s'). Kolmnurga üks külg on teada: vastase kaugus. Teised kaks saab hõlpsasti arvutada kuuli lennuaja ja kiiruste järgi.

                                        R
                                       /|
                                      /a|
     kuuli kiirus * kuuli lennuaeg   /  |
                                    /   |  
                                   /____|
                                  s'    s
                                         
                    vastase kiirus * kuuli lennuaeg

Natuke trigonomeetriat meelde tuletades avastame, et ettelaskmisnurga saab arvutada:

ettelaskmisnurk = asin(vastase kiirus / kuuli kiirus)

Kuuli lennuaeg taandub mõnusasti valemist välja. Järelikult on nurga arvutamiseks vaja teada ainult vastase kiirust ja kuuli lennukiirust.

Robocode "füüsikareeglid" annavad kuuli lennukiiruse arvutamiseks järgmise valemi:

kuuli kiirus = 20 - 3 * laksu tugevus

Vastase liikumiskiiruse saab küsida funktsiooniga e.getVelocity().

Paraku ei ole asi päris nii lihtne: meil on vaja teada vastase kiiruse seda komponenti, mis sunnib meid tema sihtimiseks toru keerama, teisisõnu: meid ei huvita kui kiiresti ta meie poole või meist eemale sõidab. Nö "vasakule-paremale" kiirust meie suhtes nimetatakse peenelt lateraalkiiruseks.

Lateraalkiiruse siht on alati täpselt risti vastase peilungiga. Oletame, et vastane liikus punktist s punkti s'. Lateraalkiiruse saamiseks tuleb korrutada kiirus (vektori pikkus) kiirusvektori ja peilungi vahelise nurga siinusega.

                 
                                        s
                                       /|
                                      /a|
                      kiirusvektor   /  |  peilung
                                    /   |  
                                   /____|
                                  s'  
                               lateraalkiirus

Vastase kiirusvektori suuna ehk kursi saame e.getHeading() funktsiooni abil. Kiirusvektori ja peilungi vahelise nurga saamiseks lahutame vastase kursist maha vastase suuna. Viimane on nurk absoluutkoordinaadistikus (null kraadi on mänguväljal otse üleval) ja peaks olema meile juba tuttav suurus.

vastase suund = peilung + minu suund
lateraalkiirus = kiirus * sin(vastase kurss - vastase suund)

Nüüd on meil olemas kõik vajalik, et kirjutada funktsioon ettelaskmisnurga arvutamisks. Kuna aga java.Math pakis leiduvad trigonomeetrilised funktsioonid kasutavad radiaane mitte kraade, tuleb kraadid enne arvutamist radiaanideks konverteerida ja pärast vastupidi tagasi. Abiks on funktsioonid Math.toDegrees(nurk) ja Math.toRadians(nurk).

    public double arvutaEttelaskmisnurk(ScannedRobotEvent e) {
        double vastase_peilung = Math.toRadians(e.getBearing());
        double vastase_kurss = Math.toRadians(e.getHeading());
        double vastase_kiirus = e.getVelocity();
        double minu_suund = Math.toRadians(getHeading());
        double kuuli_kiirus = 20 - 3 * laksuTugevus;

        double vastase_suund = minu_suund + vastase_peilung;

        double lateraalkiirus = vastase_kiirus * Math.sin( vastase_kurss - vastase_suund );

        return Math.toDegrees(Math.asin(lateraalkiirus / kuuli_kiirus));
    }

Jääb veel üle integreerida ettelaskmisnurga arvutamine robotisse (uued read on rohelised):

   public void onScannedRobot(ScannedRobotEvent e) {
       double vastase_kaugus = e.getDistance();
       double vastase_peilung = e.getBearing();
       String vastase_nimi = e.getName();

       // Kas on meie väljavalitu?
       if(vastase_nimi.equals(siga_sihikul)) {
           // Keerame tuki sea suunda ja anname tina!
           double keeramisnurk = arvutaKeeramisnurk(vastase_peilung);
           keeramisnurk = normalRelativeAngle(keeramisnurk + arvutaEttelaskmisnurk(e));
           turnGunRight(keeramisnurk);
           fire(laksuTugevus);
       }

       // Kas on lähemal, kui kõik teised?
       if(vastase_kaugus < min_kaugus) {
           uus_siga = vastase_nimi;
           min_kaugus = vastase_kaugus;
       }
   }

Iseseisev töö

Vastaseid sihtides ei ole mõtet lasta kogu aeg ühesuguse tugevusega kuulidega. Lähedal asuvale vastasele saab rohkem "haiget" teha, kui panna kirja maksimumtugevusega laks. Sinu ülesanne on lisada mingi mõistlik algoritm laksu tugevuse arvutamiseks. Alustuseks loe läbi http://testwiki.roborumble.org/w/index.php?title=Selecting_Fire_Power abiks võib olla ka robot nimega TrackFire.

Vastase valimine kauguse järgi on lahe, aga suuremas seltskonnas ragistades tuleks enne maha lasta see robot, mis otseselt Sind ennast laseb. Täienda sihtmärgi valimise algoritmi nii, et kuuliga pihta saades üritatakse vastu lasta (vähemalt mõnda aega).

Lisalugemist

Käsitletud sihtimismismeetod on äärmiselt primitiivne:

  • Eeldab, et vastane liigub sirgjooneliselt (nn lineaarne sihtimine)
  • Ei arvesta fakti, et vastane ei saa sõita läbi seina
  • Ei arvesta tuki keeramisele kuluvat aega ja laseb seetõttu natuke mööda: Mida rohkem on vastase sihikule võtmiseks vaja tukki keerata, seda ebatäpsem on lask.

Turniiril võitmiseks on vaja midagi natuke "targemat". Võiduhimulised loevad neid lehekülgi ja teevad omad järeldused: