Oryginalna strona colobot.cba.pl umarła, gdy cba.pl przestało oferować darmowy hosting. To jest statyczny mirror, pobrany w 2018. ~krzys_h
 Polski Portal COLOBOTa - COLOBOT Polish Portal
Forum - Polski Portal COLOBOTa
Strona głównaStrona główna UżytkownicyUżytkownicy GrupyGrupy StatystykiStatystyki


Poprzedni temat «» Następny temat
Przesunięty przez: Abadon
20-02-2010, 14:24
Program Defender v1
Autor Wiadomość
FE4R 


Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy
Wiek: 24
Dołączył: 21 Paź 2009
Posty: 144
Wysłany: 27-12-2009, 00:21   Program Defender v1

Chciałem opublikować mój nowy wytwór. Program do obrony biernej, czyli bez ścigania złych obcych. Wykorzystałem przyrząd celowniczy od pipoka.
Jest kilka minusów, dlatego tutaj to postuję, żeby ludzie pomogli mi znaleźć problemy z programem. :)




Kod:
public boolean object::widocznosc(point cel, int odc)
{
    point pkt;
    float D;
    float x1m, y1m, z1m;
       
    D = distance(position, cel);
   
    x1m = (cel.x - position.x) / D;
    y1m = (cel.y - position.y) / D;
    z1m = (cel.z - position.z) / D;
         
    for (int i=odc; i < D; i=i+odc)
    {     
        pkt.x = position.x + (i * x1m);
        pkt.y = position.y + (i * y1m);
        pkt.z = position.z + (i * z1m);
       
        if (pkt.z < topo(pkt)) return false;
    }
    return true;
}

public class celowanie
{
    public static int list[];
    public static object target;
    public static object me;
   
    int aiming()
    {
        point cel;
        float azymut;
        float pitchK, rollK;
        float alfa, beta, delta, gamma, epsilon, fi;
        float e, f;
       
        target = radar(list);
        cel = target.position;
       
        azymut = direction(cel);
        alfa = atan( (cel.z-me.position.z)/distance2d(me.position, cel) );
       
        pitchK = me.pitch*cos(azymut) - me.roll*sin(azymut);
        rollK  = me.roll*cos(azymut)  + me.pitch*sin(azymut);
       
        alfa -= pitchK;
        beta = rollK;
        gamma = asin( sin(alfa)*cos(beta) );
        epsilon = 0;
        fi = 0;
        delta = 0;

        e = acos ( cos(alfa)/cos(gamma) );
       
        if (alfa<0)  e = -e;
       
        f = asin( sin(beta)*sin(epsilon) );
       
        if (cos(fi)!=0) delta = acos( cos(epsilon)/cos(fi) );
        if (f<0) delta = -delta;
       
        azymut += delta;
       
        alfa = gamma;
       
        motor(0-azymut, 0+azymut);
        aim(alfa);
    }
}

extern void object::Defender1()
{
    celowanie wrog();
    wrog.me = this;
   
    while(true)
    {
        ShieldCheck(shieldLevel);
        EnergyCheck(energyCell.category, energyCell.energyLevel);
       
        wrog.list[0] = AlienWasp;
        wrog.list[1] = AlienAnt;
        wrog.list[2] = AlienSpider;
        wrog.list[3] = AlienWorm;
        wrog.list[4] = AlienEgg;
       
        while(radar(wrog.list) != null)
        {
            wrog.target = radar(wrog.list);
           
            if(wrog.target.category == wrog.list[0])
            {
                AirDefender();
            }
            else
            {
                LandDefender();
            }
           
            motor(0,0);
            wait(0.01);
           
            ShieldCheck(shieldLevel);
            EnergyCheck(energyCell.category, energyCell.energyLevel);
        }
    }
   
    wait(1);
}

void object::AirDefender()
{
    celowanie wrog();
   
    if(distance(wrog.me.position, wrog.target.position) < 42)
    {
        wrog.aiming();
       
        if(widocznosc(wrog.target.position, 10) == true)
        {
            fire(0.1);
        }
    }
}

void object::LandDefender()
{
    celowanie wrog();
   
    if(distance(wrog.me.position, wrog.target.position) < 42)
    {
        wrog.aiming();
       
        if(widocznosc(wrog.target.position, 2) == true)
        {
            fire(0.1);
        }
    }
}

void object::ShieldCheck(float n)
{
    if(n < 0.5)
    {
        object supply = radar(RepairCenter);
       
        if(supply != null)
        {
            errmode(0);
            int err = goto(supply.position);
            errmode(1);
           
            if(err != 0)
            {
                turn(direction(supply.position));
                move(distance2d(position, supply.position) - 4);
               
                do
                {
                    wait(0.1);
                    errmode(0);
                    goto(supply.position);
                    errmode(1);
                }
                while(err != 0);
            }
           
            do wait(0.1); while(n != 1);
        }
        else
        {
            message("Potrzebuje pomocy! Pozycja X: "+position.x+" Y: "+position.y);
        }
    }
}


void object::EnergyCheck(int cat, float n)
{
    if(cat == NuclearCell)
    {
        if(n < 0.1)
        {
            message("Potrzebuje pomocy! Pozycja X: "+position.x+" Y: "+position.y);
        }
    }
    else
    {
        if(n < 0.3)
        {
            object supply = radar(PowerStation);
           
            if(supply != null)
            {
                errmode(0);
                int err = goto(supply.position);
                errmode(1);
               
                if(err != 0)
                {
                    turn(direction(supply.position));
                    move(distance2d(position, supply.position) - 4);
                   
                    do
                    {
                        wait(0.1);
                        errmode(0);
                        goto(supply.position);
                        errmode(1);
                    }
                    while(err != 0);
                }
               
                do wait(0.1); while(n != 1);
            }
            else
            {
                message("Potrzebuje pomocy! Pozycja X: "+position.x+" Y: "+position.y);
            }
        }
    }
}
 
     
Berserker 
Dark Ness


Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy
Wiek: 24
Dołączył: 24 Mar 2009
Posty: 496
Skąd: Bigos
Wysłany: 27-12-2009, 02:38   

Niewiele mozna sie przyczepic, ale jednak mozna.

1)
Kod:
                    turn(direction(supply.position));
                    move(distance2d(position, supply.position) - 4);

Nie polecam uzywania instrukcji move() w robotach ktore maja lazic po bazie. Wlasciwie to wcale nie polecam uzywania instrukcji move() :)

2)
Kod:
                    do
                    {
                        wait(0.1);
                        errmode(0);
                        goto(supply.position);
                        errmode(1);
                    }
                    while(err != 0);

To juz jest tragedia.
Ta petla jest wykonywana, jesli err jest rozne od 0. Zostaje ona przerwana, gdy err bedzie rowne 0. Niby OK. Ale nigdzie nie aktualizujesz wartosci ktora jest przechowywana w zmiennej err. Efekt - petla bedzie wykonywana w nieskonczonosc. To chyba nie jest dobry pomysl w programie od ktorego zalezy przyszlosc ludzkosci.

No i takie male uwagi:
-Spodziewalem sie obrony w pelni zautomatyzowanej. Skoro juz zaczales korzystac z klas, to mogles szarpnac sie na jakiegos grabbera, ktory by mu wymienial to ogniwo.
-Malo mi sie podoba sposob sprawdzania, czy w obiekt mozna trafic. Jesli sie nie myle, on dzieli przestrzen miedzy robotem a celem na x odcinkow. Moim zdaniem jest to sposob bardzo niepraktyczny. Dokladnie sprawdza widocznosc, gdy cel jest w malej odleglosci (czyli wtedy, kiedy mamy duza szanse trafienia), ma mala dokladnosc gdy cel jest daleko (na wiekszej przestrzeni jest wieksza szansa na wystapienie gorki). O wiele lepiej jest zastosowanie sprawdzania juz o wczesniej ustalona stala odleglosc (np. 4m). Wtedy przy odleglosci 10m robot sprawdzi 2 punkty, przy odleglosci 40m 10 punktow.
-Widze, ze stosujesz pipokowe sposoby celowania (ja szczerze mowiac nigdy z nich nie korzystalem), ale nie uwzgledniasz tego, o czym pisal w co drugim poscie. Pozycja dziala to nie to samo co pozycja robota.
-Danie po prostu fire() to bezsensowna strata energii. Nie lepiej strzelac serie co jakis czas? Najlepiej zalezny od dystansu?



Dlaczego nikt w ten sposob nie komentuje moich programow :<
 
 
     
FE4R 


Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy
Wiek: 24
Dołączył: 21 Paź 2009
Posty: 144
Wysłany: 27-12-2009, 12:54   

Berserker napisał/a:
Nie polecam uzywania instrukcji move() w robotach ktore maja lazic po bazie. Wlasciwie to wcale nie polecam uzywania instrukcji move() :)

Hmmm chyba bym mógł wykorzystać Twój program Goto lub jakąś trygonometrię, żeby dojść do punktu 4 metry przed stacją.

Cytat:
To juz jest tragedia.
Ta petla jest wykonywana, jesli err jest rozne od 0. Zostaje ona przerwana, gdy err bedzie rowne 0. Niby OK. Ale nigdzie nie aktualizujesz wartosci ktora jest przechowywana w zmiennej err. Efekt - petla bedzie wykonywana w nieskonczonosc. To chyba nie jest dobry pomysl w programie od ktorego zalezy przyszlosc ludzkosci.

Ha. Tutaj zaskoczenie, bo... to działa. Też na początku myślałem, że nie będzie działać bez sprawdzenia ponownie. Sprawdziłem na obu robotach do zbieraniach rzeczy ze złoża i działa. 8-)

Cytat:
-Spodziewalem sie obrony w pelni zautomatyzowanej. Skoro juz zaczales korzystac z klas, to mogles szarpnac sie na jakiegos grabbera, ktory by mu wymienial to ogniwo.

Tak tak. Mogłem zastosować ten sposób, o którym tak trąbiłem niedawno. Zmienię to ;)

Cytat:
Malo mi sie podoba sposob sprawdzania, czy w obiekt mozna trafic. Jesli sie nie myle, on dzieli przestrzen miedzy robotem a celem na x odcinkow. Moim zdaniem jest to sposob bardzo niepraktyczny. Dokladnie sprawdza widocznosc, gdy cel jest w malej odleglosci (czyli wtedy, kiedy mamy duza szanse trafienia), ma mala dokladnosc gdy cel jest daleko (na wiekszej przestrzeni jest wieksza szansa na wystapienie gorki). O wiele lepiej jest zastosowanie sprawdzania juz o wczesniej ustalona stala odleglosc (np. 4m). Wtedy przy odleglosci 10m robot sprawdzi 2 punkty, przy odleglosci 40m 10 punktow.

Chodziło mi o to, żeby obiekty naziemne były dokładniej sprawdzane pod kątem widoczności, gdyż ich pozycja jest uzależniona od gruntu. Dla osy ustawiłem 10 metrów, gdyż może ona omijać (wznosić się ponad) górki.

Cytat:
-Widze, ze stosujesz pipokowe sposoby celowania (ja szczerze mowiac nigdy z nich nie korzystalem), ale nie uwzgledniasz tego, o czym pisal w co drugim poscie. Pozycja dziala to nie to samo co pozycja robota.

Dla programu dla robota latającego stosuję to - doktrynę amerykańską, czyli doktrynę celności, lecz gdybyś odpalił program u siebie, zobaczyłbyś, że motor(0-dir, 0+dir) strasznie 'rzuca' robotem. A to dlatego, gdyż chciałem zwiększyć skuteczność strzałów przeciwko osom. Obiekt to nie punkt, tylko 'hitbox', a jeden pocisk wystarczy, aby ją załatwić. Przy takim rozrzucie, łatwiej trafić (w mojej ocenie) szybko lecącą osę. Przy czym atakując mrówkę mogłem zastosować fire(0.1); wait(0.8);.

Cytat:
Dlaczego nikt w ten sposob nie komentuje moich programow :<

Są niesamowicie skomplikowane. Gubię się :D

EDIT:
Czy wiesz może, dlaczego nie można zadeklarować takich zmiennych jak position.z albo energyCell.energyLevel? Chodzi mi o to, że jak pewnie zauważyłeś - zadeklarowałem obiekt me jako this, ale nie mogę zrobić tego w środku samej klasy ani w metodzie aiming().
 
     
Berserker 
Dark Ness


Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy
Wiek: 24
Dołączył: 24 Mar 2009
Posty: 496
Skąd: Bigos
Wysłany: 27-12-2009, 15:29   

Cytat:
Hmmm chyba bym mógł wykorzystać Twój program Goto lub jakąś trygonometrię, żeby dojść do punktu 4 metry przed stacją.

Albo mozesz moja wersje liczenia pozycji, albo wersje z FollowPhazera. Moja:
Kod:

p = radar(PowerStation);
dest.x = p.position.x + 4*cos(orientation+direction(p.position)+180);
dest.y = p.position.y + 4*sin(orientation+direction(p.position)+180);
dest.z = topo(dest);
goto(dest);


Cytat:
Ha. Tutaj zaskoczenie, bo... to działa. Też na początku myślałem, że nie będzie działać bez sprawdzenia ponownie. Sprawdziłem na obu robotach do zbieraniach rzeczy ze złoża i działa.

Na pewno dobrze sprawdziles? Tzn doprowadziles do sytuacji, kiedy dojazd za pomoca goto() byl niedostepny, a pozniej zrobiles ten dojazd przejezdnym? Z drugiej strony, moze to wynikac z faktu, ze w zmiennej err zapisales instrukcje goto(), czyli za kazdym razem prz uzyciu zmiennej err jest ona wykonywana (malo prawdopodobne, bo przy wlasnych funkcjach funkcja jest wywolywana tylko przy ustalaniu wartosci zmiennej, ale mozliwe).

Cytat:
Chodziło mi o to, żeby obiekty naziemne były dokładniej sprawdzane pod kątem widoczności, gdyż ich pozycja jest uzależniona od gruntu. Dla osy ustawiłem 10 metrów, gdyż może ona omijać (wznosić się ponad) górki.

Nie zrozumiales o co mi chodzi. Przedstawilem roznice miedzy dzieleniem odleglosci na stala ilosc odcinkow a ustaleniem wczesniej dlugosci odcinkow. Osy i mrowki nie maja tu nic do rzeczy.

Cytat:
Dla programu dla robota latającego stosuję to - doktrynę amerykańską, czyli doktrynę celności, lecz gdybyś odpalił program u siebie, zobaczyłbyś, że motor(0-dir, 0+dir) strasznie 'rzuca' robotem. A to dlatego, gdyż chciałem zwiększyć skuteczność strzałów przeciwko osom. Obiekt to nie punkt, tylko 'hitbox', a jeden pocisk wystarczy, aby ją załatwić. Przy takim rozrzucie, łatwiej trafić (w mojej ocenie) szybko lecącą osę.

Dla robotow statycznych moim zdaniem lepiej uzywac turn() zamiast motor(). Chyba, ze ktos potrafi cos wiecej niz motor(-dir/90, dir/90) (i nie mowie tu o motor(1-dir/90, 1+dir/90) :] ) To raz. Dwa, o wiele wieksze znaczenie niz przy trafianiu ma uwzglednienie pozycji dziala w sprawdzaniu widocznosci. Po prostu czesto funkcja zwroci wartosc false, mimo, ze bys bez wiekszych problemow trafil.

Cytat:
Są niesamowicie skomplikowane. Gubię się

Jakby byly proste to bym ich nie dawal i nie plakal z powodu braku komentarzy :P A tak, to pisalem program dwa dni, poprawialem kolejny tydzien, daje na forum a tu nikt nie zauwaza go :P Nic tylko sie zastrzelic...

Cytat:
EDIT:
Czy wiesz może, dlaczego nie można zadeklarować takich zmiennych jak position.z albo energyCell.energyLevel? Chodzi mi o to, że jak pewnie zauważyłeś - zadeklarowałem obiekt me jako this, ale nie mogę zrobić tego w środku samej klasy ani w metodzie aiming().

Klasa po prostu nie uwzglednia danych korzystajacego z niej robota. Jesli juz dales w klasie zmienna (w klasach sa zmienne? :P ) me, to mozesz kontynuowac piszac me.position.z etc etc etc. Co juz zauwazyles. Jednak nie polecam deklarowac zmiennej me jako zmiennej statycznej, przy wielu robotach wykonujacych klase po prostu kolejne roboty beda nadpisywac zmienna m.

@edit 100 postow! Yeah! W ciagu 9 miesiecy :P
 
 
     
FE4R 


Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy
Wiek: 24
Dołączył: 21 Paź 2009
Posty: 144
Wysłany: 27-12-2009, 17:18   

Berserker napisał/a:
Nie zrozumiales o co mi chodzi. Przedstawilem roznice miedzy dzieleniem odleglosci na stala ilosc odcinkow a ustaleniem wczesniej dlugosci odcinkow. Osy i mrowki nie maja tu nic do rzeczy.

Z resztą usunąłem metodę sprawdzającą widoczność, gdyż zabierała zbyt dużo czasu, by skutecznie celować. Poza tym trzeba mieć też trochę głowy, gdzie stawiasz robota - najlepiej w otwartym miejscu. Szczerze mówiąc nie chciałem stworzyć zbyt skomplikowanego programu, gdyż równie dobrze zbyt dużo os mogłoby zniszczyć robota, wlatując w martwą strefę. UWzględnienie tego wszystkiego to jak programowanie robota, który będzie strzelał, bronił, gotował i wiązał krawaty.
EDIT: Kolejny powód dla którego usunąłem tą metodę - działo potrafi strzelać przez teren, jeśli nie jest to zbyt stroma góra. A ta metoda tylko mi zawadzała na praktycznie płaskim terenie. Sam swojej nie zrobię, bo jestem zbyt leniwy. Może za kilka tygodni się ruszę.

Cytat:
Dla robotow statycznych moim zdaniem lepiej uzywac turn() zamiast motor(). Chyba, ze ktos potrafi cos wiecej niz motor(-dir/90, dir/90) (i nie mowie tu o motor(1-dir/90, 1+dir/90) :] ) To raz. Dwa, o wiele wieksze znaczenie niz przy trafianiu ma uwzglednienie pozycji dziala w sprawdzaniu widocznosci. Po prostu czesto funkcja zwroci wartosc false, mimo, ze bys bez wiekszych problemow trafil.

A jak twierdzę inaczej. Podczas wykonywania funkcji turn(); działo nie może strzelać. A motor(); ma bardzo podobne działanie, czasami nawet szybsze działanie, a i strzelać można w czasie obrotu. A dir/90 jest jednym z kluczowych wyrażeń do ustawiania obrotu / kierunku.

Cytat:
Jakby byly proste to bym ich nie dawal i nie plakal z powodu braku komentarzy :P A tak, to pisalem program dwa dni, poprawialem kolejny tydzien, daje na forum a tu nikt nie zauwaza go :P Nic tylko sie zastrzelic...

No widzisz. Są praktycznie idealne. Ja nie robię takich dobrych, bo nie umiem. Chociaż trochę starszy ode mnie jesteś. :P

Cytat:
(w klasach sa zmienne? :P )

Nie nie. to chyba się jakoś inaczej nazywa w klasach, ale nie pamiętam jak. :P
 
     
Berserker 
Dark Ness


Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy
Wiek: 24
Dołączył: 24 Mar 2009
Posty: 496
Skąd: Bigos
Wysłany: 27-12-2009, 18:37   

Cytat:
A jak twierdzę inaczej. Podczas wykonywania funkcji turn(); działo nie może strzelać. A motor(); ma bardzo podobne działanie, czasami nawet szybsze działanie, a i strzelać można w czasie obrotu. A dir/90 jest jednym z kluczowych wyrażeń do ustawiania obrotu / kierunku.

Przy czasie strzelania rownym 0.1s naprawde to nie ma roznicy czy obracasz sie korzystajac z instrukcji motor() czy turn(). Roznice widac kiedy cel przemieszcza sie pod katem 90° do robota. Instrukcja motor() praktycznie przez dlugi czas obraca sie tuz za celem, nie mogac go skutecznie namierzyc. A funkcja turn() odrazu sie obraca w kierunku tej bidnej ofiary.

Cytat:
No widzisz. Są praktycznie idealne. Ja nie robię takich dobrych, bo nie umiem. Chociaż trochę starszy ode mnie jesteś.

Ja ciagle potrafie zobaczyc niedociagniecia w moich programach :P I tez mam 16 lat, po prostu wyladowalem w profilu MFI

Cytat:
Nie nie. to chyba się jakoś inaczej nazywa w klasach, ale nie pamiętam jak.

Znalazlem, to sa pola :P
 
 
     
sajmon313 
Jedi Master


Wiek: 28
Dołączył: 16 Gru 2009
Posty: 42
Skąd: /dev/uarndom
Wysłany: 27-12-2009, 19:42   

Berserker napisał/a:

Cytat:
Nie nie. to chyba się jakoś inaczej nazywa w klasach, ale nie pamiętam jak.

Znalazlem, to sa pola :P

Ale tak naprawdę to są zmienne.
Bardzo mylące nazewnictwo.
Tak samo jak metody to funkcje
_________________
Validator CBot - Prace Trwają
Ostatnia Aktualizacja: 02.01.10
 
 
     
Wyświetl posty z ostatnich:   
Nie możesz pisać nowych tematów
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum

Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Polski Portal COLOBOTa © 2008 - 2012